Mysql 系列 | 索引(优化器索引选择异常处理)

默认情况下,SQL 语句中不会选择索引,都是由优化器自动选择。

优化器为了得到最优方案,会考虑扫描行数是否使用临时表是否排序等因素。

但有时候,因为种种原因,优化器选择的并不是最佳索引。

索引选择异常处理方案

analyze table

  • 有时候 Mysql 不能准确判断数据的扫描行数,这时可以用 analyze table t 来重新统计索引信息

  • 如果 explain 的 rows 值和实际情况相差较大,可以使用重新统计的方式解决

force index

  • Mysql 会根据语法分析结果,分析出可能使用的索引作为候选项,当 force index 的索引在候选项中,则直接选择,不再评估其他候选项的代价
select * from t where a between 1 and 1000 and b between 50000 and 10000 order by b limit 1;

↓

select * from t force index(a) where a between 1 and 1000 and b between 50000 and 100000 order by b limit 1;

修改 SQL

select * from t where a between 1 and 1000 and b between 50000 and 100000 order by b limit 1;

↓

select * from t where a between 1 and 1000 and b between 50000 and 100000 order by b,a limit 1;
  • 两条 SQL 语义相同,都能得到 b 最小的一条数据

  • 修改前只根据 b 排序,直接用 b 索引,本身就是有序的,只要遍历,不再需要额外排序,所以即使扫描行数多,也被认为代价较小

  • 修改后要根据 b,a 排序,不管选择 a b 哪个索引都需要再次排序,所以最终会选择扫描行数较小的 a 索引

修改索引

  • 删掉不必要的索引,避免误用

  • 新建更合适的索引


--- 索引优化要具体问题具体分析,在实践中摸索,没有统一方案。
posted @ 2022-08-08 10:56  菜乌  阅读(160)  评论(0编辑  收藏  举报