简介
组合索引中的最左优先,以组合索引中最左边的列为起点任何连续的索引都能匹配上。如果遇到范围查询(>、<、between、like)就会停止匹配。
准备
表
CREATE TABLE `test` (
`id` bigint(11) NOT NULL,
`column1` int DEFAULT NULL,
`column2` int DEFAULT NULL,
`column3` int DEFAULT NULL,
`column4` varchar(255) DEFAULT NULL,
`column5` varchar(255) DEFAULT NULL,
`column6` varchar(255) DEFAULT NULL,
`number` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_column1_2_3` (`column1`,`column2`,`column3`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
id
为主键,组合索引idx_column1_2_3
包含三个列(column1
,column2
,column3
)
数据
分析
等值查询
以column1列为最左匹配的查询
1 where条件中根据column1
过滤
explain select * from test where column1 = 5
2 where条件中根据column1、column2
过滤
explain select * from test where column1 = 5 and column2 = 5
3 where条件汇总根据column1、column2、column3
过滤
explain select * from test where column1 = 5 and column2 = 5 and column3 = 5
结论:
可以看到以column1列为最左匹配的查询是可以执行到索引的
不以column1列为最左匹配的查询
1 where条件中根据column2、column1
过滤
explain select * from test where column2 = 5 and column1 = 5
2 where条件中根据column2、column1、column3
过滤
explain select * from test where column2 = 5 and column1 = 5 and column3 = 5
3 where条件中根据column3
过滤
explain select * from test where column3 = 5
4 where条件中根据column3、column1
过滤
explain select * from test where column3 = 5 and column1 = 5
5 where条件中根据column3、column1、column2
过滤
explain select * from test where column3 = 5 and column1 = 5 and column2 = 5
结论
- 不符合最左匹配原则,只有
column2
或column3
为条件的等值查询是不走索引的 - 只要有
column1
列存在的情况下,不论column2
或column3
顺序如何,都会走索引的,这是因为mysql会进行优化
不含有column1列的查询
1 where条件中根据column2
过滤
explain select * from test where column2 = 5
2 where条件汇总根据column2
过滤,查询column2
列
explain select column2 from test where column2 = 5
结论
这个比较特殊,虽然没有column1
没有遵循最左匹配原则,但这是索引覆盖类型,也就是能直接就在索引上进行过滤和查询列,不需要回表,所以这种也是可以走索引的。
范围查询
以column1列为最左匹配的查询
1 where条件column1等值查询,column2范围查询
explain select * from test where column1= 5 and column2 >= 5
2 where条件column1等值查询,column3 范围查询
explain select * from test where column1= 5 and column3 >= 5
3 where条件中column1等值查询,column2范围查询(范围条件>=),column3范围查询(范围条件>=)
explain select * from test where column1= 5 and column2 >= 5 and column3 >= 5
结论
可以看到范围条件是>=的,column1
、column2
、column3
三个列都能用到索引
4 where条件中column1等值查询,column2范围查询(范围条件>),column3范围查询(范围条件>)
explain select * from test where column1= 5 and column2 > 5 and column3 > 5
结论
可以看到范围条件是>的,column1
、column2
能用到索引,、column3
全表扫描
5 where条件中column1范围查询,column2等值查询
explain select * from test where column1 >= 5 and column2 = 5
不以column1列为最左匹配的查询
1 where条件column2 范围查询、column1范围查询
explain select * from test where column2 >= 5 and column1 >= 5
2 where条件column2 范围查询、column1等值查询
explain select * from test where column2 >= 5 and column1 = 5
3 where条件column2范围查询
explain select * from test where column2 > 5
4 where条件column2范围查询,只查询column2列
explain select column2 from test where column2 > 5
结论
虽然没有column1
没有遵循最左匹配原则,但这是索引覆盖类型,也就是能直接就在索引上进行过滤和查询列,不需要回表,所以这种也是可以走索引的。