1. 我们先创建表
create table test( a int , b int, c int, d int, key index_abc(a,b,c) )engine=InnoDB default
charset=utf8;
2. 插入一些数据
DROP PROCEDURE IF EXISTS proc_initData;
DELIMITER $
CREATE PROCEDURE proc_initData()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i<=10000 DO
INSERT INTO test(a,b,c,d) VALUES(i,i,i,i);
SET i = i+1;
END WHILE;
END $
CALL proc_initData();
3. 可以看到。我们建表的时候是设置了abc三列的组合索引。所以当我们
explain select * from test where a<10 ;
explain select * from test where b<10 ;
explain select * from test where c<10 ;
explain select * from test where a<10 and b <10;
explain select * from test where a<10 and c <10;
explain select * from test where b<10 and c <10;
explain select * from test where a<10 and b <10 and c<10;
可以看到数据库是否都是走了索引的
而且我们执行
explain select * from test where b<10 and a<10;
也是会走索引的。因为数据库优化器帮我们进行了优化。其实真正执行时会按索引顺序a<10 and b<10这种来执行的。
这时候为什么没有走索引了呢?最左前缀匹配原则是假设我们设置(name,age,id)顺序为索引时。name是建立索引树的第一个比较因子,所以要现有name,才知道搜索方向。
结论:
1. 联合索引abc,可以匹配a,ab,ac, abc的查询
2. ab,ac, abc的查询where顺序不影响,因为mysql优化器会帮我们进行顺序优化
3. where bc,b,c的时候,不走索引,必须从左到右匹配