慢查询优化:先看执行计划,再谈加索引

开发 · 2 分钟阅读· 235 次阅读

接口变慢,第一反应是加索引。但如果查询本身写得不对(函数包裹字段、隐式转换),加了索引也用不上。

优化的顺序应该是:看执行计划 → 判断扫描行数 → 再决定加索引还是改 SQL。

先说结论

先 EXPLAIN 看 type 与 rows,再加联合索引(区分度高的在前),能用覆盖索引就不回表。

  • type 至少要到 range,ALL 是全表扫描
  • 联合索引遵守最左前缀
  • 把查询字段放进索引可避免回表
  • 字段上加函数、隐式类型转换会让索引失效

先把问题说清楚

EXPLAIN 里最该看三列:type(访问方式)、key(用了哪个索引)、rows(预估扫描行数)。

rows 很大而结果很少,说明索引没选对或者区分度太低。

具体怎么做

按顺序执行,每步都验证完再进下一步:

  • 用 EXPLAIN 看执行计划,记录 type/key/rows
  • 确认 WHERE 条件是否命中索引最左列
  • 为多条件查询建联合索引,区分度高的放前面
  • 把 SELECT 的列收窄,尽量用覆盖索引
  • 用 EXPLAIN ANALYZE(MySQL 8)看真实耗时分布

参数与成本对照

把关键数值摊开,方便判断该选哪条路:

type 含义 评价
const/eq_ref 主键或唯一索引 最好
ref 非唯一索引匹配 好
range 范围扫描 可接受
ALL 全表扫描 需优化

慢查询优化

几个容易踩的坑

下面这些是最常见的错误做法:

  • 给每个字段单独建索引:优化器反而选错
  • 在索引列上用函数:WHERE DATE(created_at)=...
  • 字符集不一致导致隐式转换:索引失效
  • 索引过多影响写入性能

最后补两句

索引是「用写入换读取」。先确认读的性能瓶颈,再决定要不要付这个代价。

工具是手段,理解机制才是能力。命令记不住没关系,知道「该看什么」就够了。

评论 (3)

阿
阿哲

照着做了一遍,确实少走弯路。第二步最容易漏,建议顺手加个检查清单。

南
南风

比「一键脚本」有用多了,知道为什么比知道怎么做重要。

K
Kevin

补充一句:不同版本行为会变,动手前先确认自己的版本号。

发表评论

验证码

提交后需站长审核,通过后才会显示。