慢语句定位流程
慢语句定位有一套可复用的顺序:先从慢日志或监控发现候选,再聚合排序挑出性价比最高的目标,接着用执行计划定性、用实测手段确认真实瓶颈,然后优化、回归对比,最后把这条语句纳入巡检。这个顺序的价值在于避免一上来就改最刺眼的那条,而是先看总耗时占比,把时间花在收益最大的地方。
基本信息
| 起点 | 慢日志、性能视图、监控告警 |
|---|---|
| 第二步 | 聚合排序,按总耗时而不是单次耗时挑目标 |
| 第三步 | 查看执行计划,判断是索引缺失还是写法问题 |
| 第四步 | 实测确认真实行数与耗时分布 |
| 第五步 | 优化:改写语句、调整索引或治理表结构 |
| 第六步 | 回归对比并纳入巡检 |
标准步骤
- 发现:慢日志、性能视图与监控告警提供候选语句
- 聚合:按总耗时排序,先解决高频或高耗时的少数语句
- 定性:看执行计划的访问类型、扫描行数与附加信息
- 实测:用可实际执行的分析手段确认真实瓶颈步骤
- 优化:改写语句、补或改索引、清理冗余索引、治理表结构
- 回归:新旧计划与耗时对比,观察一段时间后再收尾
一条龙命令流
一条龙命令流
pt-query-digest --limit 10 /var/log/mysql/slow.log # 聚合慢日志,按总耗时排出重点
mysql -e "EXPLAIN SELECT ...;" # 定性:先看执行计划
mysql -e "EXPLAIN ANALYZE SELECT ...;" # 实测:真实行数与步骤耗时
ALTER TABLE orders ADD INDEX idx_user_created (user_id, created_at); # 按计划缺口补索引
mysql -e "EXPLAIN ANALYZE SELECT ...;" # 回归:对比前后差异各阶段关注点
| 阶段 | 关注点 | 判断依据 |
|---|---|---|
| 发现 | 慢日志与监控告警 | 确定候选语句集合 |
| 聚合 | 总耗时占比 | 先动占比最高的少数几条 |
| 定性 | 访问类型与扫描行数 | 区分缺索引与写法问题 |
| 实测 | 真实行数与步骤耗时 | 确认瓶颈真正落在哪一步 |
| 优化 | 索引与语句改动 | 改动要有明确目标 |
| 回归 | 前后计划与耗时对比 | 确认收益且无副作用 |
| 巡检 | 纳入周期检查 | 防止计划回退与索引竞争 |
优化前先立验收线,例如响应时间的分位目标:没有基线的优化等于猜,做完也无法说明是否达标。
优先处理总耗时占比高的语句:单次最慢的那条可能一天只跑一次,而一条中等耗时却每秒上千次的语句才是真正压垮系统的原因。
加了索引之后要回归其他语句:新增索引可能改变优化器选择,让原本正常的查询变慢,这是典型的索引竞争问题。
定位流程检查清单
- 确认慢日志与监控采样是否覆盖业务高峰
- 按总耗时排序挑目标,而不是按单次最慢
- 记录当前耗时与执行计划作为基线
- 一次只调整一个变量,便于归因
- 回归观察期覆盖完整业务周期
- 把优化结论写进知识库,避免同类问题重复排查
有些问题不在索引上:锁等待、连接堆积、磁盘写入能力不足都会让语句变慢,执行计划看着正常的慢语句要往这几个方向继续查,而不是反复改 SQL。
优化完成后留一段观察期:改索引与改语句都可能影响其他业务,观察期内盯住整体耗时分布与错误率,确认没有把问题转移到别处再关闭任务单。