联合索引的最左匹配原则的成因
上面我们只看的是单一的索引,接下来咱们来看看联合索引,也就是回答第二个问题。联合索引的最左匹配原则的成因。什么是联合索引呢,就是由多列组成的索引了。那亦要了解其成因,那先看看什么是最左匹配原则。
假设我们有两列 A,B 那我们对A和B设置一个联合索引,就是将A和B都设置为索引。它的顺序呢是A,B。我们在where 语句中调用where A = ?and b = ? 的时候呢,它就会走联合索引。如果我么们要where A = ?它也会走这个联合索引,但是我们调 where b = ? 的时候,没有A的时候他就不走A,B索引了。我们直接通过例子来讲解。
我们可以看到,person_info_large 是由一个联合索引的
这个联合索引由 area 和 title 这两个字段,组合成的索引。拿什么是最左匹配原则呢?
我们先来分析下面这条语句
explain select * from person_info_large where area = '深圳宝安区' and title = '标题一';
经过explain的分析呢,我们发现它走的是我们的联合索引了,possible_keys 实际它走的就是 index_area_title 那如果我们把title个删除了呢。
explain select * from person_info_large where area = '深圳宝安区';
咱们可以看到key还是 index_area_title ,就是他依然还是走我们的联合索引
而这下我们该一下删掉area
explain select * from person_info_large where title = '标题一';
我们可以看到,这时type是ALL,也就是他就不走索引了。取而代之的则是全表扫描,也就是最差的性能。
这就是最左匹配,如果创建表时 我们 把 title放在最前面,那么情况就会相反了。
还有一点要注意一下
当我们先些title 再写 area 的时候也是会走联合索引。
explain select * from person_info_large where title = '标题一' and area = '深圳宝安区';
接下来咋们来看看它的定义。
1.mysql 会一直向右匹配知道遇到范围查询 (>,<,between,like)就停止匹配,比如 a = 3 and b = 4 and c > 5 and d = 6 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果是建立(a,b,d,c)的索引则都可以用到,a,b,d 可以任意顺序。
2.= 和 in 可以乱序,比如 a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形态
接下来我们来回答最左匹配原则的成因
mysql创建复合索引的规则是首先对复合索引的最左边,也就是第一个索引数据进行排序,在第一个字段排序的基础上,再对第二个索引字段进行排序。其实就是实现了类似于order by 字段一 再 order by 字段二,这样一种排序规则。那么所以第一个字段是绝对有序的,而第二个字段就是无需的了。因此通常情况下使用第二个字段进行条件判断,就用不到索引了。这也就是mysql为什么会强调 联合索引最左匹配原则的原因。
咋们来看一个例子。
上面这张图画出了大致联合索引的长相,我们的联合索引是按照 col2,col3这样子的一个顺序去创建的。它呢就会用这个col2建立一个B+树。实际上也可能不是这个样子的因为我们也没有看到mysql里面的索引构造嘛。但是大致它应该是满足一个这么意思。比如说我们上图右侧是col3的值,它用了这么一个B+树,然后它通过关键值去查找Alice,最后找到了叶子节点上有两个Alice,Alice里面它就对应了我们这个col3的值34,77。他又会对34和77去做一个有序的排列,然后查询的时候先查询到Alice然后仔通过另外一个键也就是col3,最终定位到了我们的一个数据。因此查找的时候想走col3和col2的联合索引。就得有这个col2,单单依靠col3是没有办法去走我们B+树索引的。这就是所谓的额最左匹配原则的成因了。
小结:
如果要命中联合索引。因为col3是基于col2的基础上去排序的。所以就得有这个col2,单单依靠col3是没有办法去走我们B+树索引的。这就是所谓的额最左匹配原则的成因了。