MySQL索引优化是后端开发岗位面试中几乎必考的内容,面试官通常会结合具体的业务查询场景,考察候选人对索引设计规则、失效条件、执行计划分析等知识点的掌握程度。下面整理了几个面试中高频出现的实战案例,帮助大家梳理相关知识点。

案例一:联合索引最左匹配原则考察
面试官常给出一张用户表结构和联合索引,询问某条查询语句是否会走索引。假设用户表user的结构如下,建立了联合索引idx_name_age_city (name, age, city):
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `age` int(11) NOT NULL, `city` varchar(50) NOT NULL, `score` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `idx_name_age_city` (`name`,`age`,`city`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
此时面试官会提问以下查询是否可以使用该联合索引:
- 查询1:
SELECT * FROM user WHERE name = '张三' AND age = 20; - 查询2:
SELECT * FROM user WHERE age = 20 AND city = '北京'; - 查询3:
SELECT * FROM user WHERE name = '张三' AND city = '上海';
根据联合索引的最左匹配原则,索引是按照name -> age -> city的顺序排序的,只有查询条件中包含最左列的等值查询时,才能匹配到索引。因此查询1可以使用完整的两个列的索引,查询2无法使用索引,查询3只能使用name列的索引,city列的索引会失效。
我们可以通过explain语句验证结果,以查询3为例:
EXPLAIN SELECT * FROM user WHERE name = '张三' AND city = '上海';
执行后可以看到key列显示idx_name_age_city,key_len只对应name字段的长度,说明只使用了联合索引的第一列。
案例二:范围查询对联合索引的影响
还是基于上面的user表和联合索引idx_name_age_city,面试官会提问以下查询的索引使用情况:
SELECT * FROM user WHERE name = '张三' AND age > 20 AND city = '北京';
这里age是范围查询,根据联合索引的匹配规则,范围查询后面的列无法使用索引。因此这条查询只能使用name和age两列的索引,city列的索引会失效。如果要让city列也能使用索引,需要调整联合索引的顺序为(name, city, age),把范围查询的列放在最后。
案例三:索引失效的典型场景考察
面试官会列举一些常见的索引失效场景,要求判断查询是否会走索引,常见场景包括:
- 对索引列进行函数操作,比如
SELECT * FROM user WHERE YEAR(create_time) = 2023;,即使create_time有索引也会失效。 - 索引列参与运算,比如
SELECT * FROM user WHERE age + 1 = 21;,索引会失效。 - 使用
LIKE以通配符开头,比如SELECT * FROM user WHERE name LIKE '%三';,索引失效;如果是LIKE '张%'则可以使用索引。 - 类型隐式转换,比如
name是 varchar 类型,查询时写成SELECT * FROM user WHERE name = 123;,MySQL会自动把123转换为字符串,此时索引会失效。 - 使用
OR连接条件,如果OR前后的列有一个没有索引,整个查询的索引都会失效。
案例四:explain执行计划核心字段分析
面试官常要求解释explain执行结果中各个字段的含义,尤其是以下几个核心字段:
| 字段名 | 含义 |
|---|---|
| id | 查询的序列号,越大越先执行,相同则从上到下执行 |
| select_type | 查询类型,比如SIMPLE表示简单查询,PRIMARY表示主查询,SUBQUERY表示子查询 |
| table | 当前查询涉及的表名 |
| type | 访问类型,性能从好到坏依次是system > const > eq_ref > ref > range > index > ALL,面试中常考前几种类型 |
| possible_keys | 可能使用的索引 |
| key | 实际使用的索引,如果为NULL则表示没有使用索引 |
| key_len | 使用的索引的长度,可以判断使用了联合索引的哪些列 |
| rows | 估算的需要扫描的行数,值越小性能越好 |
| Extra | 额外信息,比如Using index表示覆盖索引,Using filesort表示需要额外排序,Using temporary表示使用临时表 |
案例五:慢查询优化实战
面试官会给出一个慢查询语句,要求给出优化方案。比如现有查询:
SELECT id, name, age FROM user WHERE city = '北京' ORDER BY score DESC LIMIT 10;
该查询执行时间超过2秒,city和score列都没有索引。优化思路如下:
- 首先为
city和score建立联合索引idx_city_score (city, score),因为查询条件是city等值查询,排序是score倒序,符合联合索引的排序规则,可以避免Using filesort。 - 查询的字段只有
id, name, age,其中id是主键,name, age不在索引中,如果需要进一步优化可以使用覆盖索引,把name, age也加入联合索引,建立idx_city_score_name_age (city, score, name, age),这样查询只需要扫描索引就可以拿到所有需要的字段,不需要回表。
优化后的查询执行计划Extra列会显示Using index,性能会有明显提升。
MySQL索引优化索引失效explain执行计划慢查询优化修改时间:2026-07-24 00:15:16