Mysql索引

按物理存储分类

从物理存储的角度来看,索引分为聚簇索引(主键索引)、二级索引(辅助索引)。

这两个区别在前面也提到了:

主键索引的 B+Tree 的叶子节点存放的是实际数据,所有完整的用户记录都存放在主键索引的 B+Tree 的叶子节点里;

二级索引的 B+Tree 的叶子节点存放的是主键值,而不是实际数据。

所以,在查询时使用了二级索引,如果查询的数据能在二级索引里查询的到,那么就不需要回表,这个过程就是覆盖索引。如果查询的数据不在二级索引里,就会先检索二级索引,找到对应的叶子节点,获取到主键值后,然后再检索主键索引,就能查询到数据了,这个过程就是回表。

InnoDB数据和索引是存放在一起的,是以聚合的方式进行存储的,是聚集索引

MyISAM数据和索引是分开来存放的,是非聚集索引,存储索引和主键

主键索引是聚集索引,存储索引和数据

非主键索引也就是二级索引是非聚集索引,存储索引和主键

按字段特性分类

从字段特性的角度来看,索引分为主键索引、唯一索引、普通索引、前缀索引。

主键索引

主键索引就是建立在主键字段上的索引,通常在创建表的时候一起创建,一张表最多只有一个主键索引,索引列的值不允许有空值。

唯一索引

唯一索引建立在 UNIQUE 字段上的索引,一张表可以有多个唯一索引,索引列的值必须唯一,但是允许有空值。

普通索引

普通索引就是建立在普通字段上的索引,既不要求字段为主键,也不要求字段为 UNIQUE。

前缀索引

前缀索引是指对字符类型字段的前几个字符建立的索引,而不是在整个字段上建立的索引,前缀索引可以建立在字段类型为 char、 varchar、binary、varbinary 的列上。

使用前缀索引的目的是为了减少索引占用的存储空间,提升查询效率。

按字段个数分类

从字段个数的角度来看,索引分为单列索引、联合索引(复合索引)。

建立在单列上的索引称为单列索引,比如主键索引;

建立在多列上的索引称为联合索引;

通过将多个字段组合成一个索引,该索引就被称为联合索引。

可以看到,联合索引的非叶子节点用两个字段的值作为 B+Tree 的 key 值。当在联合索引查询数据时,先按 product_no 字段比较,在 product_no 相同的情况下再按 name 字段比较。

也就是说,联合索引查询的 B+Tree 是先按 product_no 进行排序,然后再 product_no 相同的情况再按 name 字段排序。

因此,使用联合索引时,存在最左匹配原则,也就是按照最左优先的方式进行索引的匹配。在使用联合索引进行查询的时候,如果不遵循「最左匹配原则」,联合索引会失效,这样就无法利用到索引快速查询的特性了。

比如,如果创建了一个 (a, b, c) 联合索引,如果查询条件是以下这几种,就可以匹配上联合索引:

where a=1;

where a=1 and b=2 and c=3;

where a=1 and b=2;

需要注意的是,因为有查询优化器,所以 a 字段在 where 子句的顺序并不重要。

但是,如果查询条件是以下这几种,因为不符合最左匹配原则,所以就无法匹配上联合索引,联合索引就会失效:

where b=2;

where c=3;

where b=2 and c=3;

上面这些查询条件之所以会失效,是因为(a, b, c) 联合索引,是先按 a 排序,在 a 相同的情况再按 b 排序,在 b 相同的情况再按 c 排序。所以,b 和 c 是全局无序,局部相对有序的,这样在没有遵循最左匹配原则的情况下,是无法利用到索引的。

 当创建(a,b,c)的联合索引时,想要索引生效,只能使用a,ab,ac,abc这几种组合

   为什么??????

  因为B+树是保证你的第一个也就是最左边的字段是有序的,后面的字段都是要依赖于前面的字段才能有序(第二个依赖第一个才能有序,第三个依赖第二个才能有序),如果不从前面查找,那么无序的话只能全表扫描

联合索引优缺点

联合索引相比于一个一个去创建单列索引,磁盘的开销更小

更有利于覆盖索引的使用

效率高 不需要多次回表操作,统一一次回表就行了

MySQL聚簇索引和非聚簇索引的区别是什么?

数据存储:在聚簇索引中,数据行按照索引键值的顺序存储,也就是说,索引的叶子节点包含了实际的数据行。这意味着索引结构本身就是数据的物理存储结构。非聚簇索引的叶子节点不包含完整的数据行,而是包含指向数据行的指针或主键值。数据行本身存储在聚簇索引中

索引与数据关系:由于数据与索引紧密相连,当通过聚簇索引查找数据时,可以直接从索引中获得数据行,而不需要额外的步骤去查找数据所在的位置。当通过非聚簇索引查找数据时,首先在非聚簇索引中找到对应的主键值,然后通过这个主键值回溯到聚簇索引中查找实际的数据行,这个过程称为“回表”。

唯一性:聚簇索引通常是基于主键构建的,因此每个表只能有一个聚簇索引,因为数据只能有一种物理排序方式。一个表可以有多个非聚簇索引,因为它们不直接影响数据的物理存储位置。

效率:对于范围查询和排序查询,聚簇索引通常更有效率,因为它避免了额外的寻址开销。非聚簇索引在使用覆盖索引进行查询时效率更高,因为它不需要读取完整的数据行。但是需要进行回表的操作,使用非聚簇索引效率比较低,因为需要进行额外的回表操作。

如果聚簇索引的数据更新,它的存储要不要变化?

如果更新的数据是非索引数据,也就是普通的用户记录,那么存储结构是不会发生变化

如果更新的数据是索引数据,那么存储结构是有变化的,因为要维护 b+树的有序性

MySQL主键是聚簇索引吗?

在MySQL的InnoDB存储引擎中,主键确实是以聚簇索引的形式存储的。

InnoDB将数据存储在B+树的结构中,其中主键索引的B+树就是所谓的聚簇索引。这意味着表中的数据行在物理上是按照主键的顺序排列的,聚簇索引的叶节点包含了实际的数据行。

InnoDB 在创建聚簇索引时,会根据不同的场景选择不同的列作为索引:

如果有主键,默认会使用主键作为聚簇索引的索引键;

如果没有主键,就选择第一个不包含 NULL 值的唯一列作为聚簇索引的索引键;

在上面两个都没有的情况下,InnoDB 将自动生成一个隐式自增 id 列作为聚簇索引的索引键;

一张表只能有一个聚簇索引,那为了实现非主键字段的快速搜索,就引出了二级索引(非聚簇索引/辅助索引),它也是利用了 B+ 树的数据结构,但是二级索引的叶子节点存放的是主键值,不是实际数据。

什么字段适合当做主键?

字段具有唯一性,且不能为空的特性

性别字段能加索引么?为啥?

不建议针对性别字段加索引。

实际上与索引创建规则之一区分度有关,性别字段假设有100w数据,50w男、50w女,区别度几乎等于 0 。

实际上对于性别字段不适合创建索引,是因为select * 操作,还得进行50w次回表操作,根据主键从聚簇索引中找到其他字段 ,这一部分开销从上面的测试来说还是比较大的,所以从性能角度来看不建议性别字段加索引,加上索引并不是索引失效,而是回表操作使得变慢的。

既然走索引的查询的成本比全表扫描高,优化器就会选择全表扫描的方向进行查询,这时候建立的性别字段索引就没有启到加快查询的作用,反而还因为创建了索引占用了空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值