记录一道MySQL索引的面试题
MySQL索引是一个老生常谈的问题了,今天我们来看一道索引的面试题,先说问题,有一张表tbKey,有a,b,c三个字段,如果存在两个联合索引idx_ab(a,b)和idx_ac(a,c),如果执行如下如下sql:
SELECT * FROM tbKey WHERE a = 1;
那么会不会使用索引?会用到idx_ab和idx_ac中哪一个索引?对索引有所了解的人来说,第一个问题很简单,根据最左匹配原则,上面的查询语句肯定会使用索引,那么到底会使用哪一个索引呢?是idx_ab还是idx_ac呢?我们来实际创建场景看一下。首先,我们先创建表,并建立相应索引:
CREATE TABLE `tbKey` (
`lId` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增Id',
`a` int(11) DEFAULT '0' COMMENT 'a',
`b` int(11) DEFAULT '0' COMMENT 'b',
`c` int(11) DEFAULT NULL COMMENT 'c',
PRIMARY KEY (`lId`),
KEY `idx_ab` (`a`,`b`),
KEY `idx_ac` (`a`,`c`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
执行如下sql查看执行计划:
EXPLAIN SELECT * FROM tbKey WHERE a = 1;
从执行计划中可以看到,查询sql使用了idx_ab,为什么没有使用idx_ac呢?我们知道索引是有顺序的,是否有关呢?我们把这俩索引的顺序换一下,再看看。
果不其然,更换索引顺序后,查询使用了idx_ac。
总结:如果同一个字段被用在不同的索引中,在符合索引使用条件的情况下,根据该字段查询使用的索引和索引的顺序有关。