709 字
4 分钟
面试鸭-MySQL中使用索引一定有效吗 如何排查索引效果
MySQL中使用索引一定有效吗?如何排查索引效果?
不一定,创建了索引不一定就会用上索引,使用上索引也不代表一定效率就高。 首先,是否使用索引是看优化器计算的成本来决定的,优化器会计算全盘扫描和走索引成本,选择更低成本的方式来执行。当全表总共就几百条数据的时候,走索引可能确实不如直接全盘扫描了。但是有时候会出现统计信息不准确的情况,导致应该走索引却走了全盘扫描。
排查索引效果主要是使用EXPLAN来执行sql,可以看到MySQL选择的执行计划,主要看三个字段:type、key、rows。 type代表访问类型:ALL是全盘扫描、index是全索引扫描、ref是等值匹配、range是范围查找,如果是all那就是没有走索引,ref和range则是合理利用了索引的方式。 key代表使用的索引名称,如果是null那就是没用索引。 rows是预计要扫描的行数,数字越大代表查询代价越高。
索引失效的常见场景(8个)
- 联合索引没有遵循最左前缀原则
- 索引列上做了运算
- 索引列上用了函数
- OR的一边有非索引列
- LIKE的字符串左边有通配符的情况 LIKE “%abc%”
- 包含隐式类型转换的情况(varchar的类型赋值数字类型 导致出现自动转换)
- ORDER BY后面的字段不是主键也不是覆盖索引
- 优化器认为全盘扫描更优
问题:
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中使用索引一定有效吗如何排查索引效果/