Mysql数据库中的B+树索引可以分为聚集索引和辅助索引(非聚集索引)。本文将介绍一下两者。

聚集索引

聚集索引:指索引项的排序方式和表中数据记录排序方式一致的索引(这里不懂先放着,一会举例),每张表只能有一个聚集索引,聚集索引的叶子节点存储了整个行数据。

解释:什么叫索引项的排序方式和表中数据记录排序方式一致呢?
我们把一本字典看做是数据库的表,那么字典的拼音目录就是聚集索引,它按照A-Z排列。实际存储的字也是按A-Z排列的。这就是索引项的排序方式和表中数据记录排序方式一致。

对于Innodb,主键毫无疑问是一个聚集索引。但是当一个表没有主键,或者没有一个索引,Innodb会如何处理呢。请看如下规则:

  • 如果一个主键被定义了,那么这个主键就是作为聚集索引。
  • 如果没有主键被定义,那么该表的第一个唯一非空索引被作为聚集索引。
  • 如果没有主键也没有合适的唯一索引,那么innodb内部会生成一个隐藏的主键作为聚集索引,这个隐藏的主键是一个6个字节的列,该列的值会随着数据的插入自增。

辅助索引

辅助索引:辅助索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,还存储了一个指向改行数据的聚集索引建的书签。

辅助索引可以理解成字典按偏旁去查字。

借幅图举例子,图来自https://www.cnblogs.com/s-b-b/p/8334593.html

image.png

我们直接看B+树的Leaf Level中的叶节点,只存放了辅助索引那列的数据,并不包含整个行的数据,但是他后面存放了一个“指针”,比如黄色的Rudd,后面存的是4:705:01,代表完整的行记录在第705页的第一条记录。

所以非聚集索引有二次查询的问题:
非聚集索引叶节点仍然是索引节点,只是有一个指针指向对应的数据块,因此如果使用非聚集索引查询,而查询列中包含了其他该索引没有覆盖的列,那么他还要进行第二次的查询,查询节点上对应的数据行的数据。

如何解决非聚集索引二次查询的问题:
建立两列以上的索引,即可查询复合索引里的列的数据而不需要进行回表二次查询,如index(col1, col2),执行下面的语句:

select col1, col2 from t1 where col1 = '213';

因为复合索引的列包括了col1和col2,不需要查询别的列,所以不需要进行二次查询。

要注意使用复合索引需要满足最左侧索引的原则,也就是查询的时候如果where条件里面没有最左边的一到多列,索引就不会起作用。(看不懂的话后面讲)

通俗的讲讲最左索引原则吧:
假设创建了复合索引index(A,B,C),那么其实相当于创建了如下三个组合索引:
index(A,B,C)
index(A,B)
index(A)
这就是最左索引原则,就是从最左侧开始组合。

知乎上关于最左索引问题的比较不错的回答:https://www.zhihu.com/question/36996520/answer/93256153

所以说如果查询的时候,where语句没有最左边的一列或多列,就不会使用建立的索引去查询。

参考资料:
https://www.cnblogs.com/s-b-b/p/8334593.html