联合索引
上文讲解了索引的底层结构,但是留了一个尾巴,就是没有去讲复合索引。今天来继续梳理复合索引,所谓复合索引即是由多个字段组成的一条索引。
例如下表
CREATE TABLE `test` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`a` varchar(10) NOT NULL,
`b` varchar(10) NOT NULL,
`c` varchar(10) NOT NULL,
`d` varchar(10) NOT NULL,
`e` varchar(10) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_a_b_c` (`a`,`b`,`c`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
如下索引就是一个联合索引
idx_a_b_c
(a
,b
,c
) USING BTREE
那么怎么样的sql会走联合索引呢????
答案是最左前缀。
那么!!!什么又是最左前缀?下面我们用sql的形式来进行案例讲解。
SQL 一
select * from test where a = '333' and b = '333' and c = '333';
这个sql会不会走索引?我想你就是猜也肯定能猜到他会走吧,答案是会走,看下执行计划
SQL 二
select * from test where a = '333' and b = '333';
这个SQL会走复合索引吗,答案是会,结论你先接着,最后会给大家分析。看下执行计划
SQL 三
select * from test where a = '333' and c = '333';
这条SQL同样会走索引,也许这个时候你的内心会有一个结论了,但是可能不对!看下执行计划
SQL 四
select * from test where b = '333' and c = '333';
这个SQL会走索引吗?你的答案是不是模糊了呢?看下执行计划
答案是不会走联合索引,至此我们来总结联合索引的最左前缀匹配,所谓最左前缀匹配即是where条件必须有联合索引的第一个字段。
SQL 五
select * from test where c = '333' and b = '333' and a = '333';
这条sql会不会走联合索引???看下执行计划
明很显走了索引,至此我们又得出一个结论,联合索引与where条件的顺序无关
小结
- 联合索引的最左前缀匹配指的是where条件一定要有联合索引的第一个字段
- 是否走联合索引与where条件的顺序无关,只与字段有关
联合索引数据结构
联合索引大致类似上面的B+树结构,所以当索引的维护其实是以第一个字段来优先排序的,如果你的查询条件里没有第一个字段就没法通过索引比较来定位数据
覆盖索引
覆盖索引其实是一种特殊的联合索引,怎么理解呢,即是你查询的字段的所有数据都在索引上,不需要再进行一次回表查询,这样的索引即为覆盖索引。例如下sql即会走覆盖索引
SELECT a,b,c from test where a = '333';