直接查看Threads_running和SHOW FULL PROCESSLIST的Time字段可快速判断当前是否被慢SQL拖垮:Command为Query且Time>5秒即为阻塞源,>30秒需优先处理;State为sending data或Sorting result说明排序或传输瓶颈;Host异常IP提示调用模式问题;Threads_running持续>20表明内核调度饱和;mysqldumpslow可聚合慢日志定位高频慢点;Handler_read_rnd_next和Handler_read_full_table升高揭示全表扫描或回表问题。

直接看 Threads_running 和 SHOW FULL PROCESSLIST 里的 Time 字段,比翻慢查询日志快得多——这是判断“现在是否正在被慢SQL拖垮”的第一反应。
查当前活跃连接和执行时间(紧急定位“现行犯”)
系统突然变慢、CPU飙升时,SHOW FULL PROCESSLIST 是唯一不依赖配置、秒出结果的手段。它能立刻暴露正在吃资源的 SQL,无需等待日志滚动或定时归集。
-
Command是Query且Time> 5 秒,基本可判定为当前阻塞源;超过 30 秒的必须优先处理 -
State是sending data或Sorting result,说明数据已查出但还在传输或排序,大概率是ORDER BY/LIMIT没走索引,或返回字段太多 -
Host列若出现陌生 IP 或大量相同应用 IP,可能是某服务批量拉取未限流,不是单条 SQL 问题,而是调用模式问题 - 注意:
SHOW PROCESSLIST默认只显示前 100 字符的 SQL,加FULL才能看到完整语句,别漏掉关键WHERE条件
看全局线程状态(判断是否已形成积压)
SHOW STATUS LIKE 'Threads%' 提供的是宏观水位信号。单靠 PROCESSLIST 可能只看到一两条长 SQL,但实际已有几十个连接卡在排队,这才是“严重”的标志。
-
Threads_running持续 > 20(InnoDB 默认并发线程上限是 32),说明内核调度已饱和,新请求开始排队 -
Threads_connected突增但Threads_running不高,可能是连接池泄漏,不是慢 SQL 问题,别误判 -
Threads_created每秒增长快,说明连接频繁新建,常伴随短连接滥用或连接未释放,间接加重慢 SQL 影响
快速扫慢查询日志(验证历史高频慢点)
日志不是用来“等它发生”,而是确认哪些 SQL 已经反复拖累系统。别手动 tail -f,用 mysqldumpslow 直接聚合:
-
mysqldumpslow -s t -t 5 /var/log/mysql/slow.log:找出总耗时最高的 5 条,它们可能单次不长但执行极频繁 -
mysqldumpslow -s c -t 5 /var/log/mysql/slow.log:执行次数 Top 5,比如一个SELECT COUNT(*)每分钟跑 200 次,再快也扛不住 - 如果日志里大量出现
Query_time: 0.000xxx但带Rows_examined: 500000,说明 SQL 很快但扫描行数巨大——这是log_queries_not_using_indexes = 1开启后才捕获的隐形杀手
检查 Handler_read_* 指标(确认是否在全表扫描)
这个指标比 EXPLAIN 更真实,反映实际执行时的物理读行为,不受缓存干扰:
-
SHOW STATUS LIKE 'Handler_read%'中,Handler_read_rnd_next高,说明大量随机回表,SELECT *+ 没覆盖索引是典型原因 -
Handler_read_full_table> 0,代表有全表扫描发生(哪怕EXPLAIN显示type=ALL,你也得看这个值是否真在涨) - 对比
Handler_read_key(走索引读)和Handler_read_next(索引顺序读),比值过低说明索引利用率差,不是没建索引,而是索引设计没对上查询模式
真正容易被忽略的是:很多“严重慢 SQL”根本不会出现在慢查询日志里——因为 long_query_time 设了 1 秒,而它的执行时间是 0.9 秒,但每秒执行 50 次,累计 CPU 占用远超一条 5 秒 SQL。这时候 Handler_read_* 和 Threads_running 的持续高位,才是更本质的信号。











