MySQL慢查询日志生效需同时满足三条件:slow_query_log=ON(字符串)、log_output=FILE或TABLE、long_query_time对新会话生效;仅变量为ON不等于真正记录,须用SELECT SLEEP(2)验证Slow_queries计数是否增加。

MySQL 慢查询日志不是默认开启的,开了也不代表真在记录——很多线上问题卡在这一步就停住了。关键不是“怎么开”,而是“开得对不对、有没有真正捕获到业务真实的慢点”。
确认慢查询日志是否真正生效
别只看SHOW VARIABLES LIKE 'slow_query_log'返回ON就以为万事大吉。必须三件事同时满足:
-
SHOW VARIABLES LIKE 'slow_query_log'返回字符串 ON(不是 1 或空) -
SELECT @@global.slow_query_log和SELECT @@session.slow_query_log都为 1;如果 session 是 0,说明当前连接不记日志,需退出重连 -
SHOW GLOBAL STATUS LIKE 'Slow_queries'初始值为 0,执行SELECT SLEEP(2)后必须变成 1,否则日志链路中断
还要检查日志路径父目录权限:ls -ld $(dirname /var/lib/mysql/mysql-slow.log),确保 MySQL 进程用户(如 mysql)有写权限;Windows 下注意 XAMPP 路径被 UAC 拦截。
设置合理的 long_query_time 阈值
默认 10 秒对 Web 接口毫无意义——超时通常在 2 秒内。但设太低又会日志爆炸。建议分步调整:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 先设为
1.0,观察 1–2 小时,用mysqldumpslow -s t -t 10 /path/to/slow.log看实际耗时分布 - 若发现大量查询集中在 0.8–1.2 秒,再下调到
0.5 -
SET GLOBAL long_query_time = 0.5后必须退出当前客户端重连,旧连接仍按老值判断 - 避免设为 0:它会记录所有查询(包括
SELECT 1),磁盘 IO 和文件体积飙升,仅限临时诊断
注意:MySQL 5.7 及以前版本对小数精度支持有限,0.098 秒可能被截成 0.09 秒而不触发记录。
捕获“隐性慢”:未走索引但执行快的查询
log_queries_not_using_indexes = ON 不是打开就完事。单独启用会把 WHERE id = -1 这种扫 0 行的语句也记下来,日志量爆炸且无分析价值。
- 必须同步设置
min_examined_row_limit = 100(或更高,如 500),表示“未走索引且扫描行数 ≥ 100 才记录” - 该参数在部分云厂商定制版中不支持动态设置,需写入
my.cnf并重启 MySQL - 它和
long_query_time定位的问题类型不同:long_query_time抓显性慢,log_queries_not_using_indexes + min_examined_row_limit抓本不该慢却没走索引的“隐性慢”
从日志里一眼识别瓶颈在哪
慢日志不是纯 SQL 列表,每条记录自带诊断线索。重点盯这三项:
- Rows_examined 远大于 Rows_sent:比如扫了 50 万行只返回 10 行,大概率 WHERE 条件没走索引,或索引选择性差
- Lock_time 高:说明锁等待严重,可能是事务长、隔离级别高或热点行竞争
-
Query_time 高但 Rows_examined 很低:可能卡在磁盘 I/O、网络传输或解析阶段,需结合
performance_schema进一步排查
注意:慢查询日志不记录物理备份(如 XtraBackup)的 I/O 操作,只捕获 SQL 层行为。若备份慢,要查 performance_schema.file_summary_by_instance 或系统级 iostat。


















