MySQL B+树如何实现联合索引

MySQL索引的数据结构B+树
传送门:闲聊MySQL:(七)InnoDB之索引结构


好了,前情回顾完毕,复习了一下聚簇索引和二级索引的B+树结构,下面进入正题,我们来说说联合索引的结构。
联合索引的B+树结构
user,有几个字段
id、
c1、
c2、
c3、
c4,其中
id是主键,
c1、c2、c3字段建立联合索引,那么执行下面几个SQL,来看一下索引执行情况:
select * from user where c1= 12 and c2= 14 and c3 = 3 索引全匹配
select * from user where c1= 12 and c2= 14 索引部分匹配
select * from user where c1= 12 and c3 = 3 // 索引部分匹配
select * from user where c2= 12 and c3 = 3 // 索引无法匹配

name、age、point也会生成一个索引树,同样是B+树的结构,只不过它的
data部分存储的是联合索引所在行的主键值。
联合索引的查找方式
select * from user where c1= 12 and c2= 14 and c3 = 3。
第一个索引的第一个索引列为1,12大于1; 第二个索引的第一个索引列为56,12小于56; 于是从这俩索引的中间读到下一个节点的磁盘文件地址,从磁盘上Load这个节点,通常伴随一次磁盘IO,然后在内存里去查找。 当Load叶子节点的第二个节点时又是一次磁盘IO,比较第一个元素,b=12,c=14,d=3完全符合,于是找到该索引下的data元素即ID值,再从主键索引树上找到最终数据。

最左匹配原则
c1、c2、c3索引,相当于创建了(c1)、(c1、c2)(c1、c2、c3)三个索引,看完下面你就知道为什么相当于创建了三个索引。
我们看,联合索引是首先使用多列索引的第一列构建的索引树,用上面的例子就是优先使用c1列构建,当c1列值相等时再以c2列排序,若c2列的值也相等则以c3列排序。我们可以取出索引树的叶子节点看一下。

索引的第一列也就是c1列可以说是从左到右单调递增的,但我们看c2列和c3列并没有这个特性,它们只能在c1列值相等的情况下这个小范围内递增,如第一叶子节点的第1、2个元素和第二个叶子节点的后三个元素。
由于联合索引是上述那样的索引构建方式及存储结构,所以联合索引只能从多列索引的第一列开始查找。所以如果你的查找条件不包含c1列如(c2, c3)、(c2)、(c3) 是无法应用缓存的,以及跨列也是无法完全用到索引如(c1, c3),只会用到c1列索引。
结语
文章转载自老宣说,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




