RDS for MySQL 慢日志只有耗时?三步定位执行计划

举报
yd_230305343 发表于 2026/10/28 08:26:54 2026/10/28
【摘要】 线上 RDS for MySQL 开了慢查询日志,阈值 1 秒,日志里躺着一堆这样的记录:# Query_time: 3.21 Lock_time: 0.00 Rows_examined: 1284392 Rows_sent: 20只有耗时和扫描行数,看不到走了哪个索引、为什么慢,排查全靠猜。其实慢日志的设计就是只记「账单」,不记「路线」——执行计划要自己复现。分享一套三步定位法。 第...

线上 RDS for MySQL 开了慢查询日志,阈值 1 秒,日志里躺着一堆这样的记录:

# Query_time: 3.21  Lock_time: 0.00  Rows_examined: 1284392  Rows_sent: 20

只有耗时和扫描行数,看不到走了哪个索引、为什么慢,排查全靠猜。其实慢日志的设计就是只记「账单」,不记「路线」——执行计划要自己复现。分享一套三步定位法。

第一步:先圈定问题 SQL

在 RDS 控制台「日志管理 → 慢日志」里按耗时排序还不够,重点看扫描行数与返回行数的比值:扫描 128 万行只返回 20 行,说明绝大部分工作量浪费在无效扫描和排序上,这类语句就是优化的主目标。慢日志量大时可以导出后用 pt-query-digest 按 SQL 指纹聚合,按总耗时占比排优先级,避免盯着单条偶发慢查询使劲。

第二步:同参数复现执行计划

拿到完整 SQL 和参数后,在同库执行 EXPLAIN(MySQL 8.0 还可用 EXPLAIN ANALYZE 看每一步的实际耗时)。四个关键列:

  • type:出现 ALL 就是全表扫描;
  • key:实际命中的索引是不是预期那个;
  • rows:优化器预估的扫描行数,和慢日志的 Rows_examined 对得上,才说明复现的是同一个现场;
  • Extra:Using filesort、Using temporary 是最常见的两个危险信号。

注意必须用慢日志里的真实参数复现:参数不同、数据分布不同,优化器完全可能选另一条计划,拿着别的参数 EXPLAIN 出来的结论去改索引,只会越改越乱。

第三步:交叉验证,别只信一张计划表

  • 查 performance_schema.events_statements_summary_by_digest,看这个 SQL 指纹的累计扫描行、平均耗时,确认它是不是长期作案;
  • 优化前后对比 SHOW SESSION STATUS LIKE 'Handler_read%' 的计数变化,扫描量真的降下来才算改对;
  • 最后回到慢日志,用同一语句的 Query_time 前后对比收尾验收。

常见根因与对策

现象 根因 对策
扫描百万行返回几十行 缺索引或索引列顺序不对 等值列在前、范围列在后建联合索引;排序字段能进索引就避免 filesort
索引在、就是不走 对索引列用了函数或隐式类型转换 改写 SQL,让索引列保持「裸奔」
计划时好时坏 统计信息过期、数据倾斜 ANALYZE TABLE 更新统计信息
LIMIT 深分页越翻越慢 大偏移量扫描丢弃 改键集分页(用上次最大 id 做游标)

慢查询治理的顺序应该是「先定位、再复现、后动手」,而不是看到慢就加索引——加错索引的代价是每次写入都要多维护一棵 B+ 树。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。