先确认是数据库慢而非接口或网络问题,链路追踪显示DB耗时高才深入排查;DB调用占比超70%再查MySQL,重点看慢查询日志、执行计划突变、锁和事务状态。

先确认是不是数据库慢,而不是接口或网络
接口响应变慢,不等于 MySQL 慢。链路追踪里看到 DB 耗时高,才值得往下查;否则可能卡在网关、缓存失效、远程调用超时,甚至应用层死循环。SkyWalking 或 Arthas 能快速定位耗时毛刺在哪一环。如果 DB 调用耗时占比超过 70%,再进 MySQL 查。
看慢查询日志有没有新出现的“异常 SQL”
不是所有慢 SQL 都一直慢,很多是某天突然变慢——比如索引失效、统计信息过期、数据倾斜加剧。重点查:slow_query_log 是否开启,long_query_time 是否设得太松(线上建议设为 1);log_queries_not_using_indexes 建议打开,能捕获那些“看似快、实则全表扫”的隐患语句。
- 执行
SHOW VARIABLES LIKE 'slow_query%'和SHOW VARIABLES LIKE 'long_query_time'确认配置生效 - 日志路径通常在
/var/lib/mysql/localhost-slow.log,用mysqldumpslow -s t -t 10提取最近最耗时的 10 条 - 注意对比:同一条 SQL,今天耗时 8 秒,上周平均 80ms,那就要怀疑数据分布、索引或执行计划变更
用 EXPLAIN 对比执行计划是否“突变”
同一 SQL,昨天走 ref 类型索引,今天变成 ALL,说明执行计划变了。这不是代码改了,而是底层条件变了——常见原因有:INNODB 统计信息陈旧、字段值分布严重倾斜、隐式类型转换导致索引失效。
- 执行
EXPLAIN SELECT ...,重点比对type、key、rows、Extra四列和历史记录 -
rows突然从几千跳到几十万?大概率是优化器误判,可手动加FORCE INDEX验证 -
Extra出现Using filesort或Using temporary?检查排序字段是否在索引里,或WHERE条件是否破坏了最左前缀
查锁和事务状态,排除“假慢”
SQL 本身很简单,但执行时间长达数秒,十有八九是等锁。尤其在高峰期,一个未提交的事务或长事务会阻塞后续所有操作。
- 执行
SHOW PROCESSLIST,找状态为Waiting for table metadata lock或Locked的线程 - 执行
SELECT * FROM information_schema.INNODB_TRX,看是否有运行超 60 秒的事务 - 执行
SHOW ENGINE INNODB STATUS\G,搜TRANSACTIONS和LATEST DETECTED DEADLOCK,确认是否存在锁冲突
真正难排查的,往往不是“哪条 SQL 慢”,而是“为什么它今天突然慢”。执行计划漂移、统计信息滞后、小事务卡住大查询——这些不会报错,但会让性能断崖式下跌。盯住 rows 和 key 的变化,比盯着耗时数字更有价值。


















