
1) 【一句话结论】:核心是添加复合索引(class_id, score)并优化SELECT列,利用覆盖索引减少I/O,同时调整索引顺序匹配查询条件顺序,提升查询性能。
2) 【原理/概念讲解】:索引通过B树结构存储列数据,类似图书馆书签,能快速定位满足条件的行。对于范围查询(score > 80)和排序(ORDER BY score DESC),复合索引(多列索引)可同时满足过滤和排序需求,避免全表扫描。若索引列顺序与查询条件顺序一致(class_id在前,score在后),能先过滤class_id=1的行,减少后续处理的数据量。
3) 【对比与适用场景】:
| 索引类型 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 普通索引 | 仅包含索引列的键值 | 需回表查询(从索引找主键,再查数据行) | 单一列查询或排序 | 多列查询时需多次回表 |
| 覆盖索引(复合索引) | 索引包含查询所需的所有列(如class_id, score) | 无需回表(直接从索引获取数据) | SELECT * 或查询列都在索引中 | 索引列顺序需匹配查询条件顺序(先过滤列在前) |
4) 【示例】:
原SQL:
SELECT * FROM student WHERE class_id = 1 AND score > 80 ORDER BY score DESC LIMIT 10;
优化后(添加复合索引):
-- 创建复合索引
CREATE INDEX idx_class_score ON student (class_id, score);
-- 优化查询
SELECT * FROM student
WHERE class_id = 1 AND score > 80
ORDER BY score DESC
LIMIT 10;
解释:索引class_id, score先通过class_id过滤class_id=1的行,再通过score过滤score>80,最后直接利用索引排序,避免全表扫描和额外排序。
5) 【面试口播版答案】:
“面试官您好,针对这个查询,核心优化点是添加复合索引并优化SELECT列。原SQL使用SELECT *会扫描所有列,而实际只需要score和class_id等列,可以改用SELECT class_id, score, ...(具体列)来减少I/O。同时,添加复合索引class_id, score,因为查询条件是class_id=1和score>80,且排序字段是score,索引列顺序与查询条件顺序一致,能先过滤class_id=1的行,再通过score过滤,最后直接利用索引排序,避免全表扫描和额外排序。这样能显著提升查询性能。”
6) 【追问清单】:
7) 【常见坑/雷区】: