直接查 mysql.slow_log 表比解析日志文件更高效,前提是配置 log_output = 'TABLE';需先验证 slow_query_log=ON 且 log_output='TABLE',再通过 SQL 查询排序、聚合分析慢查询,重点关注高频非慢 SQL。

直接查 mysql.slow_log 表,比翻日志文件快得多,前提是已配置 log_output = 'table'。
确认慢查询日志是否启用且输出到表
很多团队开了日志但没设 log_output,结果日志写进文件,还得用 mysqldumpslow 或手动 grep ——效率低还容易漏。先验证当前配置:
- 执行
SHOW VARIABLES LIKE 'slow_query_log',确认值为ON - 执行
SHOW VARIABLES LIKE 'log_output',必须是'TABLE'(不是'FILE'或'FILE,TABLE') - 如果返回空或
OFF,需先运行:SET GLOBAL slow_query_log = 'ON'; SET GLOBAL log_output = 'TABLE';
注意:log_output = 'TABLE' 会让所有慢 SQL 直接写入 mysql.slow_log 视图,支持 SQL 查询、排序、聚合,不用解析文本格式。
按执行时间倒序查最慢的几条 SQL
mysql.slow_log 表里有 start_time、query_time、sql_text 字段,直接查就行:
SELECT query_time, lock_time, rows_sent, rows_examined, sql_text FROM mysql.slow_log ORDER BY query_time DESC LIMIT 10;
关键点:
-
query_time是真实执行耗时(秒),含锁等待;lock_time单独列出锁等待时间,两者差值大说明存在锁竞争 -
rows_examined比rows_sent大很多,大概率是全表扫描或索引未覆盖 -
sql_text可能被截断(默认 1024 字节),若语句长,需结合mysqld配置中的max_long_data_size调整
临时调低 long_query_time 抓取“伪慢 SQL”
有些 SQL 执行 300ms,不算慢,但高频调用拖垮整体响应——这类隐患靠默认 1 秒阈值发现不了。可临时设为 0.1 秒:
- 执行
SET GLOBAL long_query_time = 0.1; - 观察 10–30 分钟后查
mysql.slow_log,重点看query_time在 0.05–0.3 秒之间、rows_examined却上万的语句 - 排查完立刻恢复:
SET GLOBAL long_query_time = 1;(不恢复会导致日志爆炸,磁盘撑满)
这个操作风险高但见效快,适合压测后或用户集中反馈卡顿的时段使用。
别只盯着单条 SQL 的 query_time
一条 query_time = 8s 的 SQL 很扎眼,但更危险的是 100 条 query_time = 0.8s 的相同语句每秒执行 20 次——它们加起来占满连接池和 CPU。所以查完最慢的,还要补一句:
SELECT COUNT(*) cnt, ROUND(AVG(query_time),3) avg_time, sql_text FROM mysql.slow_log WHERE start_time > NOW() - INTERVAL 1 HOUR GROUP BY sql_text ORDER BY cnt DESC, avg_time DESC LIMIT 5;
真正要优先优化的,往往是那些“不慢但高频”的 SQL,尤其是出现在应用循环里的 SELECT —— 它们不会触发慢日志告警,却悄悄吃掉数据库吞吐。


















