709 字
4 分钟
面试鸭-MySQL中使用索引一定有效吗 如何排查索引效果

MySQL中使用索引一定有效吗?如何排查索引效果?#

不一定,创建了索引不一定就会用上索引,使用上索引也不代表一定效率就高。 首先,是否使用索引是看优化器计算的成本来决定的,优化器会计算全盘扫描和走索引成本,选择更低成本的方式来执行。当全表总共就几百条数据的时候,走索引可能确实不如直接全盘扫描了。但是有时候会出现统计信息不准确的情况,导致应该走索引却走了全盘扫描。

排查索引效果主要是使用EXPLAN来执行sql,可以看到MySQL选择的执行计划,主要看三个字段:type、key、rows。 type代表访问类型:ALL是全盘扫描、index是全索引扫描、ref是等值匹配、range是范围查找,如果是all那就是没有走索引,ref和range则是合理利用了索引的方式。 key代表使用的索引名称,如果是null那就是没用索引。 rows是预计要扫描的行数,数字越大代表查询代价越高。

索引失效的常见场景(8个)#

  1. 联合索引没有遵循最左前缀原则
  2. 索引列上做了运算
  3. 索引列上用了函数
  4. OR的一边有非索引列
  5. LIKE的字符串左边有通配符的情况 LIKE “%abc%”
  6. 包含隐式类型转换的情况(varchar的类型赋值数字类型 导致出现自动转换)
  7. ORDER BY后面的字段不是主键也不是覆盖索引
  8. 优化器认为全盘扫描更优

问题:#

EXPLAIN 里的 type 字段, ref 和 range 有什么区别?#

ref表示等值匹配,比如WHERE a = ‘1’;range表示范围匹配,比如where id>100,需要扫描一段连续的区间。性能上ref通常比range好,因为ref可以准确匹配到某个位置,而range得匹配到某个位置后往后扫描。

怎么知道优化器是不是选错索引了?#

可以使用force index来强制选择某个索引来运行。如果用上这个索引运行会更快,则说明优化器选错了索引。还可以用Analyze table来更新统计信息,让优化器重新计算。另外MySQL 8.0可以使用EXPLAIN Analyze来查看分析的预估行数和实际行数,如果差距较大则统计信息不准。

覆盖索引为什么能提升查询性能?#

覆盖索引指的是查询时,需要查询的字段都存在于索引中,因此可以不用回表,也就是不用再回去聚簇索引再查找一遍,可以减少很多次随机io,因此性能会更高。

面试鸭-MySQL中使用索引一定有效吗 如何排查索引效果
http://www.shineacz.top/posts/面试鸭-mysql中使用索引一定有效吗如何排查索引效果/
作者
shineAcZ
发布于
2026-03-13
许可协议
CC BY 4.0