SHOW PROCESSLIST仅显示当前未结束的活跃SQL,不区分快慢;需结合Time(持续秒数)和State(如Sending data)人工识别潜在慢查询,且普通用户仅可见自身线程。

show processlist 只显示“正在跑”的SQL,不区分快慢
很多人以为 SHOW PROCESSLIST 能直接筛出“慢查询”,其实它只列出当前活跃连接中**尚未结束**的语句,不管执行了0.1秒还是10秒。它不读慢日志,也不受 long_query_time 控制。真正卡住数据库的那条SQL,可能就藏在几十上百行输出里,但你得自己肉眼识别状态和时间。
关键看两列:Time(单位秒,是该线程持续运行时长,不是SQL执行耗时)和 State(比如 Sending data、Copying to tmp table、Sorting result 这些都是危险信号)。
- 如果
Time值明显高于业务正常响应(比如 >5s),且State长期卡住,基本就是问题SQL -
root用户能看到所有连接;普通用户只能看到自己的,所以排查时要用高权限账号 - 执行
SHOW FULL PROCESSLIST才能看清完整SQL(否则超长SQL会被截断)
如何用 information_schema.PROCESSLIST 筛选“疑似慢”的活跃查询
直接查表比命令更可控,还能加条件过滤。MySQL 5.7+ 把运行中线程信息存在 information_schema.PROCESSLIST 表里,可以这样筛:
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM information_schema.PROCESSLIST WHERE TIME > 5 AND COMMAND = 'Query' AND INFO IS NOT NULL;
注意点:
-
TIME > 5是经验阈值,不是long_query_time的复刻,只是帮你聚焦长时间运行的线程 - 排除
COMMAND != 'Query'的连接(比如Sleep、Connect),它们不执行SQL -
INFO IS NOT NULL过滤掉空SQL(比如某些连接池心跳) - 这个表是只读视图,不能
DELETE或UPDATE,想杀掉线程得用KILL [ID]
别把 slow_query_log 和当前执行混为一谈
慢查询日志(slow_query_log)记录的是**已经执行完且超时**的SQL,而 SHOW PROCESSLIST 看的是**还没结束**的。两者互补,但完全不是一回事。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
常见误解:
- “我开了
long_query_time=1,为什么PROCESSLIST里没看到标红的慢SQL?”→ 因为它还没跑完,日志根本不会记 - “日志里有条SQL跑了8秒,现在去
PROCESSLIST查不到”→ 对,它早执行完了,只剩日志记录 - 线上接口卡死,但慢日志空空如也?大概率是某条SQL正卡在中间没返回,得靠
PROCESSLIST抓现行
kill 掉卡住的查询要谨慎
找到可疑线程后,KILL [ID] 是最直接的止血方式,但风险不小:
- 如果是事务中的
UPDATE或DELETE,KILL会触发回滚,IO压力可能瞬间飙升 - 某些长事务持有表级锁,
KILL后释放锁的过程本身也可能阻塞其他操作 - 先用
SELECT * FROM information_schema.INNODB_TRX看它是否在事务里,再决定是否KILL - 生产环境建议加
--skip-external-locking参数启动MySQL,减少KILL引发的锁竞争
真正难的从来不是“怎么查”,而是判断哪条SQL该杀、什么时候杀、杀完会不会引发连锁反应——这些没法靠命令自动回答。










