今日,无意间打开了脉脉,看到了一条某大厂的一面的关于数据库的面试题。点进去看了一眼

细想一下,感觉想要答得完美还是挺不容易的,于是就赶紧做了一番实验。验证一下自己的想法,同时记录一下。
问题
数据库中4个字段id,a,b,c。其中id主键,有两个联合索引,ab,ac下面几个查询都会用到哪些索引
select * from t where a=xx and b=xx and c=xx;
select * from t where a=xx and c=xx and b=xx;
select * from t where a=xx and (b=xx or b=xx);
问题看上去貌似挺简单的,但细想又觉得好像很难回答的很全面。
首先先放上我实验后的一些结论
结论
01
查询条件b和c的先后顺序,不影响最终的索引选择
02
ab,ac联合索引建立的先后顺序会影响索引的选择
03
MySQL优化器会根据possible_keys中的索引键顺序选取索引,如果能满足需求则不继续选择后面的索引。possible_keys内可以选取的索引键就是安装创建顺序排列的。
04
按顺序只选取possible_keys内的第一个索引的情况包括:abc三个字段都唯一、abc三个字段都不唯一、a唯一bc不唯一。
05
当只有b和c其中一个字段唯一时,会分别选取ab或ac的组合索引。
06
or会导致索引失效,因此只有a字段能用到索引,所以第三个是索引是用到了ac组合索引中的a
以上结论部分为个人理解,可能有不对的地方,希望大家留言讨论交流。
实验验证

先建两张表t1,t2,两张表的唯一区别就是建立联合索引的顺序不同。
t1 先建ab联合索引,再建ac联合索引
t2 先建ac联合索引,再建ab联合索引
一
先建ab联合索引,再建ac索引
01
a b c 都唯一


根据explain的显示结果,交换where条件中b和c的位置,对索引的选取没有影响。最终选择了使用ab联合索引。
02
a b c 不唯一
不唯一的情况分为四种:
a,b,c三者都不唯一


explain结果显示都使用了idx_ab索引
a b不唯一,c唯一


explain显示优化器最后选择了idx_ac索引。
a c不唯一,b唯一


explain显示优化器最终选择了idx_ab联合索引
a 唯一,b c不唯一

选择了ab联合索引,与都不唯一的情况相同
小结
1、查询条件b和c的顺序,不影响最终的索引选择
2、只有当a,b字段不唯一,c字段唯一的情况下才会选择ac联合索引,其余情况都会选择ab联合索引
二
先建立ac联合索引,再建立ab联合索引
01
a b c 都唯一


根据explain的显示结果,交换where条件中b和c的位置,对索引的选取没有影响。最终选择了使用ac联合索引。
02
a b c 不唯一
不唯一的情况分为四种:
a,b,c三者都不唯一


explain显示只选择了ac联合索引
a b不唯一,c唯一


explain显示选取了ac联合索引
a c不唯一,b唯一

显示使用了ab联合索引
a唯一,b c不唯一

显示使用了ac联合索引
小结
1、查询条件b和c的位置,不影响最终的索引选择
2、只有当a,c字段不唯一,b字段唯一的情况下才会选择ab联合索引,其余情况都会选择ac联合索引
根据这两次实验,ab和ac组合索引的创建先后顺序不同,explain显示选择的索引键的不同,推测出了之前的结论。
第三个sql
select * from t where a=xx and (b=xx or b=xx);

explain显示用到的索引键为idx_ac,key_len 为5个字节,a字段类型为int,占4个字节,字段允许为空,需要用1个字节来记录。因此这里or会导致索引失效,只有a字段用到了索引。




