慢查询日志需同时满足开启开关、合理设置long_query_time、明确输出目标三条件;默认10秒阈值基本无效,应设为1或0.5秒,并用pt-query-digest分析归一化SQL及Rows_examined/Sent比值定位真瓶颈。

慢查询日志不是“开了就能用”,必须同时满足三个条件:日志开关打开、long_query_time设得合理、日志输出目标明确——缺一不可。默认值 long_query_time = 10 在线上基本抓不到有效 SQL,这是最常被忽略的起点。
确认当前配置再操作,别信“我记得开了”
直接执行以下两条命令,看真实状态:
SHOW VARIABLES LIKE 'slow_query_log';<br>SHOW VARIABLES LIKE 'long_query_time';
如果 slow_query_log 返回 OFF,说明根本没开;如果 long_query_time 是 10.000000,意味着只记超过 10 秒的查询——这在现代业务里几乎等于不记录。
-
slow_query_log_file的路径也要查一下:SHOW VARIABLES LIKE 'slow_query_log_file';,确认 MySQL 进程有写权限,否则日志会静默失败 - 临时开启必须用
SET GLOBAL,SET SESSION无效 - MySQL 8.0+ 配置文件里写
slow_query_log = ON会启动失败,必须写成slow_query_log = 1
临时开启:适合快速验证或紧急排查
不用重启服务,但重启后失效。建议阈值设为 1 或 0.5(单位秒,支持小数):
SET GLOBAL slow_query_log = 1;<br>SET GLOBAL long_query_time = 1;<br>SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';<br>SET GLOBAL log_queries_not_using_indexes = 1;
注意:log_queries_not_using_indexes = 1 会显著增加日志量,仅在索引问题排查期启用;slow_query_log_file 路径必须提前创建并授权:mkdir -p /var/log/mysql && chown mysql:mysql /var/log/mysql。
- 执行后立即生效,但新连接才受新
long_query_time影响(已有连接仍沿用旧值) - 检查是否真有日志产生:
show global status like 'Slow_queries';,数值应随慢 SQL 增长 - 不要设
long_query_time = 0,MySQL 会自动转为10,这是个隐藏陷阱
永久开启:配置文件 + 重启 + 权限校验
编辑 /etc/my.cnf 或 /etc/mysql/my.cnf 的 [mysqld] 段,关键项必须这样写:
[mysqld]<br>slow_query_log = 1<br>slow_query_log_file = /var/log/mysql/slow.log<br>long_query_time = 1<br>log_output = FILE<br>min_examined_row_limit = 100
log_output = FILE 很重要——某些版本默认写进表 mysql.slow_log,pt-query-digest 无法直接读取;min_examined_row_limit = 100 可过滤掉“查 3 行却花了 2 秒”的锁等待干扰项。
- 路径目录必须存在且属主为
mysql用户,否则 MySQL 启动失败或日志静默丢失 - 改完配置后必须重启:
sudo systemctl restart mysqld(或mysql,依发行版而定) - 重启后立刻验证:
SHOW VARIABLES LIKE 'slow_query_log';和tail -f /var/log/mysql/slow.log看是否有新条目
分析日志别用 mysqldumpslow,直接上 pt-query-digest
mysqldumpslow 只做简单聚合,SQL 归一化能力弱,漏掉大量模式相似但参数不同的慢查;pt-query-digest 才是生产环境事实标准:
pt-query-digest /var/log/mysql/slow.log --limit 10
它能自动归一化 SQL(比如把 WHERE id=123 和 WHERE id=456 视为同一类)、统计 Rows_examined、Query_time 分位数、按客户端 IP 切片,还能输出 HTML 报告。
- 确保日志是 FILE 格式,
pt-query-digest不支持直接解析表存储的慢日志 - 加
--filter '$event->{Bytes} > 1024'可过滤小结果集查询,聚焦高 IO 场景 - 分析结果里重点关注
Rows_examined和Rows_sent比值,远大于 1 说明存在低效扫描
真正难的不是开启日志,而是判断哪条 SQL 值得优化:一条 Rows_examined = 500万 但 Rows_sent = 1 的查询,比十条各查 100 行的慢查更值得优先处理。日志只是线索,EXPLAIN 才是最终判决书。


















