Spring 与 MySQL 整理
MySQL 索引失效?先把 SQL 和执行计划拿出来
最左前缀不是一句万能口诀,索引使用也不只有“用”和“不用”两种状态。
先回答:联合索引 (a, b, c),范围条件后面的列就完全没用了吗?
不能这样一概而论。范围条件可能限制后续列继续收缩索引扫描区间,但后续列仍可能参与索引条件下推、覆盖扫描或过滤。具体效果要结合 SQL、索引顺序、MySQL 版本和执行计划判断。
从联合索引的顺序开始
B+ 树复合索引按键列的顺序组织。对 (a, b, c) 来说,约束前面的列通常更有利于定位连续的索引范围。写出查询示例,比单独背“最左匹配”更清楚。
优化器可能选择不同访问路径,某些版本还支持特定条件下的跳跃扫描等优化。因此既不能说“缺第一列必然完全不能用索引”,也不能据此认为索引顺序无关紧要。
看执行计划时关注什么
EXPLAIN
SELECT player_id, score
FROM marble_daily
WHERE score_date = '2026-10-15'
ORDER BY score DESC
LIMIT 20;
这是一个基于项目表名的示例查询,不代表线上性能结论。可以先看 key、type、rows、filtered、Extra 等字段,再结合表结构、实际分布和查询目标分析。
MySQL 8.0.18 起支持 EXPLAIN ANALYZE,它会执行查询并给出运行时信息。生产环境中使用前要评估 SQL 的开销,而不是把它当作完全没有执行成本的查看命令。
需要一起考虑的因素
- 对索引列施加函数、发生隐式类型转换或使用某些模糊匹配方式,可能影响可利用的索引访问路径。
- 即使存在可用索引,优化器也可能根据数据分布和成本选择全表扫描。
- 覆盖索引、回表、排序和扫描行数,是不同维度,不能只看到 key 非空就宣布查询高效。
- 联合索引会增加写入、存储与维护成本,应围绕真实查询建立,避免把所有字段都加成索引。
延伸阅读
以上为个人整理。涉及版本实现和线上使用时,请结合对应文档与实际测试判断。