直接执行 show processlist 可查看活跃连接及语句,重点关注 time 持续增长且 state 为 sending data 或 copying to tmp table 的查询;普通用户需确认权限,加 full 防 sql 截断,优先筛选 time > 60 且 command = 'query' 的记录,并结合 explain、innodb status、threads_running、buffer_pool_wait_free 及系统 iowait 综合分析。

怎么看当前正在跑的慢查询
直接连上 MySQL 执行 SHOW PROCESSLIST,它会列出所有活跃连接和它们正在执行的语句。重点看 Time 列(单位秒)和 State 列——如果某个连接的 Time 持续增长、State 是 Sending data 或 Copying to tmp table,大概率就是它在拖慢服务器。
-
root用户能看到全部连接;普通用户只能看到自己的,排查前确认权限 - 默认只显示前 100 行,加
SHOW FULL PROCESSLIST防止 SQL 被截断 - 注意区分
Command是Query还是Sleep:长期Sleep一般不是问题源,别误杀连接
如何快速识别“卡住”的查询语句
光看 PROCESSLIST 有时不够直观,尤其当 SQL 被截断或状态不明确时。更可靠的方式是结合 INFORMATION_SCHEMA.PROCESSLIST 做筛选:
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE TIME > 60 AND COMMAND = 'Query' ORDER BY TIME DESC LIMIT 10;
这个查询把运行超 60 秒的普通查询拎出来,按耗时倒序排。关键点:
-
INFO字段可能为NULL(比如被权限限制或语句太长被截),不能全信 - 有些语句看似短,但触发了全表扫描或没走索引,实际很慢——得配合
EXPLAIN看执行计划 - 注意
HOST和USER,批量应用或定时任务常从固定 IP/账号发起,方便定位服务方
为什么 kill 掉一个线程后负载还是下不去
常见错觉:kill 了几个长连接,LOAD 或 CPU 却没明显下降。原因通常是这些线程只是“症状”,不是“病根”:
- 底层可能是磁盘 I/O 瓶颈(比如大量
Writing to net或Locked状态),杀 query 不解决 IO 压力 - 存在隐式锁等待:一个事务 hold 住行锁,其他几十个查询在排队等它,只 kill 排队者没用
- MySQL 内部线程池或连接数已打满(
max_connections被占满),新请求在排队,表现为整体响应变慢 - 某些语句 kill 后会回滚大事务,反而加剧磁盘写压力,短暂推高负载
查完 processlist 后该盯哪几个关键指标
processlist 是入口,不是终点。接下来必须交叉验证这几个地方,否则容易误判:
- 用
SHOW STATUS LIKE 'Threads_%'看Threads_running(真正干活的线程数)是否远高于平时基线 - 检查
SHOW ENGINE INNODB STATUS\G中的SEMAPHORES和TRANSACTIONS部分,找锁等待链和长时间未提交事务 - 确认
innodb_buffer_pool_wait_free是否持续非零——说明 buffer pool 不够用,频繁刷脏页 - 别忘了看系统层:
top里 MySQL 进程是不是真占 CPU,还是磁盘iowait高,那得查iostat -x 1
processlist 是快照,而负载是持续现象。单靠它定位问题,就像只看一张照片猜车祸原因——得把上下文拼起来看。











