Home Mysql最左匹配原则
Post
Cancel

Mysql最左匹配原则

前言

如果问你mysql最左匹配原则是什么?我们大部分人都会脱口而出:在组合索引时,满足最左优先,从左往右匹配,遇到>、<、>=、<=、between、like就会停止匹配。然而真的是这样吗?

实验

准备

新建表:mysql_index_test

字段: mysql_index_test表字段

联合索引:B+tree索引,字段a和b是联合索引,字段c和d是联合索引
mysql_index_test表字段

测试数据:
mysql_index_test表字段

Query1

select * from mysql_index_test where a > 5 and b = 0;

问:用到了索引的哪些字段?
答:索引a_b_idx中的:a 执行计划:

EXPLAIN select * from mysql_index_test where a > 5 and b = 0;

mysql_index_test表字段
key_len=4(字段a,int类型并且不为null)

Query2

select * from mysql_index_test where a >= 5 and b = 0;

问:用到了索引的哪些字段?
答:索引a_b_idx中的:a和b 执行计划:

EXPLAIN select * from mysql_index_test where a >= 5 and b = 0;

mysql_index_test表字段
key_len=4(字段a,int类型并且不为null) + 4 (字段b,int类型并且不为null) = 8

Query3

select * from mysql_index_test where a BETWEEN 1 and 2 and b = 0;

问:用到了索引的哪些字段?
答:索引a_b_idx中的:a 执行计划:

EXPLAIN select * from mysql_index_test where a BETWEEN 1 and 2 and b = 0;

mysql_index_test表字段
key_len=4(字段a,int类型并且不为null) + 4 (字段b,int类型并且不为null) = 8

Query4

select * from mysql_index_test where c like 'a%' and d = 1;

问:用到了索引的哪些字段? 答:索引c_d_idx中的:c和d 执行计划:

EXPLAIN select * from mysql_index_test where c like 'a%' and d = 1;

mysql_index_test表字段
key_len=120(字段c,varchar(30)并且不为null) + 2(字段c变长类型的字段需要+2) + 4 (字段d,int类型并且不为null) = 126

原因分析

mysql的组合索引结构如下图: mysql_index_test表字段

联合索引的特点:a字段全局有序,b字段值在a相同的情况下局部有序

sql1:a>5 and b = 0:
满足a > 5范围的b是无序的,无法定位到具体的开始位置,所以b字段无法用到b索引;
sql2和sql3:a>=5 and b=0 和 a BETWEEN 1 and 2 and b = 0,mysql的between左右到包含,可以等同于>=和<=:
满足a >= 5范围中a=5时的b是有序的,可以定位到具体的a=5,b=2的开始位置,所以可以用到b索引;
sql4:like ‘a%’ and d = 1,匹配规则aXXX,类似于>=,所以也可以用到d索引

结论

mysql联合索引的最左匹配原则:在遇到范围查询(如 >、<)的时候,就会停止匹配,也就是范围查询的字段可以用到联合索引,但在范围查询字段后面的字段都无法用到联合索引。 >=、<=、BETWEEN、like 前缀匹配的范围查询,并不会停止匹配。

This post is licensed under CC BY 4.0 by the author.

策略模式(Strategy)

责任链模式 (Chain of Responsibility)

Trending Tags