Yihui’s Blog

MySQL 中如何进行 SQL 调优?

日期:2026-07-11
标签:#面试 #八股 #后端 #MySQL #数据库 #场景题

一句话答案

SQL 调优以慢日志和真实指标定位目标,通过执行计划分析访问路径、扫描行数、排序和临时表,再从索引、SQL、数据模型和业务访问方式逐层优化并回归验证。

面试口语版

我先用慢查询日志、APM 和数据库指标找到高总耗时或高频 SQL,而不是凭感觉优化。拿到真实参数后执行 EXPLAIN ANALYZE,看实际行数与估算是否偏差、使用了哪个索引、是否全表扫描、回表、临时表或文件排序。然后考虑建立符合过滤和排序的联合索引、减少返回列和扫描范围、改写 OR/子查询、消除 N+1 和深分页。最后在近似生产数据上对比耗时、扫描行数和资源,观察锁、写放大与索引空间,避免只让单条查询变快却拖慢写入。

关键细节

  • 联合索引顺序结合等值、范围、排序和选择性设计,不只看单列基数。
  • EXPLAIN 是估算,MySQL 8 的 EXPLAIN ANALYZE 会真实执行,要谨慎用于生产写 SQL。
  • 隐式类型转换、函数包裹索引列和前导通配符可能破坏索引利用。
  • 优化目标应看总资源和 P99,不只看一次执行时间。

面试官追问

  1. type=ALL 一定代表 SQL 很差吗?
  2. 联合索引字段顺序怎么定?
  3. 为什么加索引后反而变慢?

面试官追问参考答案

1. type=ALL 一定代表 SQL 很差吗?

不一定。小表全表扫描可能比走索引再回表更便宜,查询大部分数据时优化器也可能正确选择全扫。要结合实际扫描行数、表大小、过滤比例和总耗时判断。

2. 联合索引字段顺序怎么定?

优先满足核心查询的等值条件,再考虑范围、排序和覆盖;高选择性有帮助但不是唯一规则。范围条件之后的列通常难继续用于缩小扫描范围,但可能用于索引下推或覆盖,最终需用执行计划验证。

3. 为什么加索引后反而变慢?

索引会增加写入维护、页分裂、缓存占用和优化器选择空间;低选择性索引大量回表可能比全扫慢。统计信息过期也可能选错计划,因此要看实际执行并评估读写整体收益。

学习清单

  • 会阅读 EXPLAIN ANALYZE 核心字段。
  • 能从 SQL、索引和业务调用三层优化。
Maintained by · YihuiEdit on GitHub

Keep reading

View all posts