慢查询治理

慢查询是数据库性能问题的线索来源:开启慢查询日志,按总耗时贡献排序,用执行计划定位扫描行数与临时表,建立治理台账跟踪闭环。

慢查询治理是什么

慢查询是数据库性能问题最主要的线索来源。开启慢查询日志并按总耗时贡献排序,可以优先处理影响最大的语句;再用执行计划确认扫描行数、索引命中与临时表使用情况,决定是补索引、改写查询还是调整数据模型。

为什么按总耗时排序

单次耗时极端的查询看着刺眼,但真正拖垮数据库的往往是每秒调用上千次、每次几十毫秒的语句。总耗时等于平均耗时乘以调用次数,按这个口径排序才能找到真正值得优化的对象。优化完成后要有回归监控,否则索引被后续变更影响而退化时,没有人会及时发现。

定位手段

定位手段
-- 查看执行计划与扫描行数
EXPLAIN ANALYZE SELECT ...;

-- 慢日志按总耗时排序:平均耗时 × 调用次数
-- 优先处理高频中等耗时,而不是单次极端值
-- 对比优化前后:扫描行数、回表次数与延迟

治理步骤

  • 开启慢日志,阈值按业务分位与磁盘 IO 承受度校准
  • 按总耗时排序,先治理贡献最高的语句
  • 用执行计划检查扫描行数、索引命中、临时表与排序方式
  • 按序优化:补改索引、改写查询、调整数据模型,缓存放最后
  • 记录修复前后耗时对比,纳入台账并周期性复扫

动手之前先确认三件事

第一,确认这条查询是否真的在关键路径上:报表类慢查询可以放到只读副本或离线任务里,不必挤占在线资源。第二,确认问题来自 SQL 本身还是数据模型:如果一张表承担了互不相关的职责,加再多索引也解决不了扩展问题。第三,确认优化不会破坏写入:为读路径加索引会拖慢写路径,要同时观察写入延迟的变化。

治理顺序先看总耗时贡献:单次十秒但每月只跑一次的查询,未必比每次五十毫秒、每秒上千次的查询更值得优先处理。

易错点

  • 只清理单次最慢的查询,忽略高频中等耗时项,数据库压力依旧
  • 治理后未加回归监控,索引退化或数据量增长导致问题重现
  • 用缓存掩盖慢查询而不解决根因,缓存失效时数据库直接被打垮
  • 慢日志阈值设置失当,要么噪音过多无人看,要么漏掉真实问题

数据来源与参考

  • 《高性能 MySQL(第 4 版)》
  • MySQL 8.0 Reference Manual:Slow Query Log
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌