慢查询日志适合筛选值得调查的语句,但“耗时”只是症状。一次调用的墙钟时间可能包含执行、等待锁、读盘、传输结果和应用端消费。调查前应固定 SQL 文本、参数类型与代表性参数值、调用时间段、并发水平、返回行数,并确认采样窗口内是否发生批处理或流量突增。这样才能让优化前后的比较有意义。
先在相同数据规模和参数下取得 EXPLAIN。如果服务器版本支持 EXPLAIN ANALYZE,它会执行语句并报告实际行数和迭代耗时;不能把它当作纯静态检查,写语句可能产生副作用,重查询也可能给系统增加负载。可以先在副本或隔离环境复现,生产使用前明确语句是否只读、结果规模是否受控。
沿执行树从叶节点向上看:表以什么方式访问,使用哪个索引,估算和实际各处理多少行,过滤条件在何处应用,以及排序、分组是否需要额外工作。实际行数远高于估算,通常意味着统计信息无法代表当前分布,或参数命中了倾斜数据;这时盲目新增索引可能只是掩盖估算偏差。先验证不同参数是否触发相同访问路径,并观察计划估算与实际的偏差是否稳定。
可以用扫描放大比做初筛:扫描行数除以最终返回行数。比值很高时,检查谓词是否可用、类型是否一致、函数或隐式转换是否阻碍索引范围访问,以及过滤列的组合顺序是否合理。若访问索引后仍需读取许多表记录,可能存在大量回表。若主要耗时落在排序或临时处理中间结果,检查是否能先缩小候选集合,或是否需要匹配查询顺序的复合索引。“用了索引”本身不是验收标准。
同一计划有时快、有时慢,往往需要检查并发而不是继续改索引。结合数据库等待事件、锁等待、存储延迟、CPU使用和连接排队,区分执行器在做工作还是在等待资源。若数据库执行时间低而应用端耗时高,应核对网络往返、结果集字节数及客户端是否逐行处理。将服务端语句耗时与应用调用耗时放在同一时间线上,能够避免把传输问题误判为扫描问题。
一项优化通过验收,应能解释执行工作量为何下降,并在代表性参数和并发下持续改善目标延迟,且没有把压力转移成明显的 CPU、读盘、写入或锁等待回归。保存 SQL、参数范围、计划、指标窗口和改动版本,后续数据增长或分布变化时才有可比基线。核心顺序是:日志选问题,计划定位工作,等待指标找环境因素,重复基准验证收益。