快速定位拖慢数据库的sql需分四步:先设long_query_time=2开启慢日志,再用mysqldumpslow -s t -t 10分析top 10慢查询;接着用explain重点看type(避免all)、rows(扫描行数)和extra(避免using filesort/using temporary);然后通过show full processlist观察time>60且state异常的会话;最后结合show global status中innodb_buffer_pool_reads、created_tmp_disk_tables等指标确认资源瓶颈。

慢查询不是靠猜出来的,而是靠工具一层层剥开的。直接看日志、查状态、跑 EXPLAIN,比反复改SQL更省时间。
怎么快速定位哪条SQL在拖慢整个库?
别等用户投诉才动手。先打开慢查询日志,阈值设为 long_query_time = 2(生产环境够用),再用 mysqldumpslow 扫一遍:
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
它会按平均耗时排序,直接告诉你 top 10 慢查询。注意看 Count 和 Time 两列——高频+高耗时的组合,优先处理。
- 如果日志里全是
SELECT * FROM ... WHERE ... ORDER BY ... LIMIT ...这类深分页,大概率是using filesort或全表扫描 -
pt-query-digest比mysqldumpslow更细,能统计锁等待、返回行数、客户端分布,适合压测后复盘 - MySQL 8.0+ 可以直接查
performance_schema.events_statements_summary_by_digest表,免去解析日志步骤
EXPLAIN 看什么才真正有用?
EXPLAIN 不是只看有没有用上索引,关键看三处:
-
type列:优先要ref或range,出现all就是全表扫描,得加索引 -
rows列:预估扫描行数。如果远大于实际结果集(比如查10条却扫10万行),说明索引没走对或缺失 -
Extra列:Using filesort表示排序没走索引;Using temporary表示用了临时表——这两项通常意味着需要复合索引或重写查询
特别提醒:key_len 能帮你判断联合索引用了几列。比如索引是 (a,b,c),key_len 显示 10,说明只用到了前两列 a 和 b,c 没生效。
SHOW PROCESSLIST 能看出什么真实问题?
执行 SHOW FULL PROCESSLIST,重点盯 Time 和 State 两列:
-
Time > 60且State = 'Sending data':多半是大结果集没加LIMIT,或者没走索引导致扫描太多行 -
State = 'Waiting for table metadata lock':有 DDL(如ALTER TABLE)正在执行,阻塞了其他查询 -
State = 'Locked'或'Updating'时间很长:可能是事务没提交,或行锁冲突严重
注意:SHOW PROCESSLIST 默认只显示当前用户进程,加 WITH CONSISTENT SNAPSHOT 或用 performance_schema.threads 查更全的视图。
哪些状态变量暴露了底层瓶颈?
运行 SHOW GLOBAL STATUS 后,重点关注这几个值:
-
Innodb_buffer_pool_read_requests和Innodb_buffer_pool_reads:前者是逻辑读,后者是物理读。比值Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests超过 1% 就说明缓存不够,innodb_buffer_pool_size得调大 -
Created_tmp_tables和Created_tmp_disk_tables:内存临时表 vs 磁盘临时表。后者占比高,说明tmp_table_size和max_heap_table_size设得太小 -
Threads_connected接近max_connections:连接池泄漏或应用没正确释放连接
这些数字本身没意义,要和基线对比。比如某天凌晨 Created_tmp_disk_tables 突增 5 倍,大概率是某条新上线的 SQL 开始大量落盘。
诊断不是一步到位的事。一个 EXPLAIN 看不出锁竞争,SHOW PROCESSLIST 抓不住瞬时 IO 尖峰,slow_log 也漏掉刚好卡在阈值下的查询。真正有效的做法,是把这几类工具串起来用:先从日志找目标 SQL,再用 EXPLAIN 看执行路径,接着用 PROCESSLIST 观察实时阻塞,最后用状态变量确认资源水位。漏掉任何一环,都可能把优化方向搞反。











