0


【Mysql性能优化系列】一文了解MySQL最左匹配原则

前言

索引匹配遵循最左匹配原则,那是为什么呢?欲知详情,请看下文分解。

概述

MySQL存储引擎InnoDB 索引都是B-tree数据结构。空间索引使用 R-trees。

InnoDB架构图:

在这里插入图片描述

B-Tree与B+Tree区别

Innodb 存储引擎的 B-Tree 索引实际使用的存储结构实际上是 B+Tree。

B+TreeB-Tree 数据结构的基础上做了改造,在每一个Leaf Nod 上面出了存放索引键的相关信息之外,还存储了指向与该 Leaf Node 相邻的后一个 LeafNode 的指针信息(增加了顺序访问指针),这主要是为了加快检索多个相邻 Leaf Node 的效率考虑。

联合索引树

创建一个

(name,age,address)

的联合索引,索引树如下:
在这里插入图片描述
上图中name的值是有顺序的按首字母的 a,b,c 排,而age和address的值是没有顺序的。

所以age = 38这种查询条件没有办法利用索引,因为联合索引首先是按name排序的,age是无序的。

最左匹配

最左匹配原则:最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。

假如建立联合索引(a,b,c)

全值匹配查询

全值匹配指的是和索引中的所有列进行匹配。

select * from table_name where a ='1' and b ='2' and c ='3' 
select * from table_name where b ='2' and a ='1' and c ='3' 
select * from table_name where c ='3' and b ='2' and a ='1'

在这里插入图片描述

where子句几个搜索条件顺序调换不影响查询结果,因为Mysql中有查询优化器,会自动优化查询顺序

匹配最左前缀

只使用索引的第一列。

select * from table_name where a ='1'
select * from table_name where  b ='2' 
select * from table_name where  c ='3'
select * from table_name where  b ='1' and c ='3'

这些没有从最左边开始,最后查询没有用到索引,用的是全表扫描

在这里插入图片描述

select * from table_name where a ='1' and c ='3'

在这里插入图片描述

如果不连续时,只用到了a列的索引,b列和c列都没有用到

匹配列前缀

匹配某一列值得开头部分。

select * from table_name where a like 'As%';//前缀都是排好序的,走索引查询
select * from table_name where  a like '%As'//全表查询
select * from table_name where  a like '%As%'//全表查询

匹配范围值

select * from table_name where  a >1 and a <3

可以对最左边的列进行范围查询

select * from table_name where  a >1 and a < 3 and b >1;

多个列同时进行范围查找时,只有对索引最左边的那个列进行范围查找才用到B+树索引,也就是只有a用到索引,在1<a<3的范围内b是无序的,不能用索引,找到1<a<3的记录后,只能根据条件 b > 1继续逐条过滤。

精确匹配某一列并范围匹配另外一列

如果左边的列是精确查找的,右边的列可以进行范围查找

select * from table_name where  a =1 and b >3;

a=1的情况下b是有序的,进行范围查找走的是联合索引。

排序

一般情况下,我们只能把记录加载到内存中,再用一些排序算法,比如快速排序,归并排序等在内存中对这些记录进行排序,有时候查询的结果集太大不能在内存中进行排序的话,还可能暂时借助磁盘空间存放中间结果,排序操作完成后再把排好序的结果返回客户端。
MySQL中把这种再内存中或磁盘上进行排序的方式统称为文件排序。

文件排序非常慢,但如果order子句用到了索引列,就有可能省去文件排序的步骤:
因为b+树索引本身就是按照上述规则排序的,所以可以直接从索引中提取数据,然后进行回表操作取出该索引中不包含的列就好了。

order by的子句后面的顺序也必须按照索引列的顺序给出,比如

select * from table_name order by a,b,c limit 10;

在这里插入图片描述

如下颠倒顺序的没有用到索引:

select * from table_name order by b,c,a limit 10;

在这里插入图片描述

如下用到部分索引:

select * from table_name order by a limit 10;
select * from table_name order by a,b limit 10;

如下联合索引左边列为常量,后边的列排序可以用到索引:

select * from table_name where a =1 order by b,c limit 10;

在这里插入图片描述

在这里插入图片描述
点赞 收藏 关注


本文转载自: https://blog.csdn.net/qq_35764295/article/details/126980311
版权归原作者 三省同学 所有, 如有侵权,请联系我们删除。

“【Mysql性能优化系列】一文了解MySQL最左匹配原则”的评论:

还没有评论