必须开启慢查询日志并合理设置long_query_time(建议0.5~2秒)才能有效捕获慢sql;pt-query-digest因支持sql归一化、细粒度指标分析和可定制切片,显著优于mysqldumpslow。

慢查询日志必须开启才能分析,但直接开全局 + 默认 long_query_time=10 什么都抓不到;pt-query-digest 是目前最实用的分析工具,比 mysqldumpslow 更准、更细、更可定制。
如何确认并正确开启 slow_query_log
先看当前状态,别凭印象操作:
-
SHOW VARIABLES LIKE 'slow_query_log';返回OFF就没开 -
SHOW VARIABLES LIKE 'long_query_time';常见默认是10.000000,意味着只记超过 10 秒的查询——线上基本看不到有效数据 - 临时开启(会话级无效,必须用
GLOBAL):SET GLOBAL slow_query_log = ON;,SET GLOBAL long_query_time = 0.5;(建议设为 0.5~2,单位支持小数秒) - 路径不指定时,
slow_query_log_file默认落在 MySQL 数据目录下,文件名类似hostname-slow.log,注意该路径 MySQL 进程要有写权限 - 如果要记录“没走索引”的语句,加一句:
SET GLOBAL log_queries_not_using_indexes = ON;
配置文件里怎么写才不会重启失败
修改 /etc/my.cnf 或 /etc/mysql/my.cnf 的 [mysqld] 段,注意这几点:
- 不要写
slow_query_log = ON,MySQL 8.0+ 要求写成slow_query_log = 1,否则启动报错 -
slow_query_log_file路径必须存在且可写,比如/var/log/mysql/slow.log,提前mkdir -p /var/log/mysql && chown mysql:mysql /var/log/mysql -
long_query_time设为0.1可捕获毛刺型慢查,但日志体积暴涨,不建议长期开启 - 加上
log_output = FILE明确输出到文件(避免某些版本默认写进mysql.slow_log表,不方便用 pt 工具读) - 可选但推荐:
min_examined_row_limit = 100,过滤掉只查几行却慢的干扰项(如锁等待)
为什么不用 mysqldumpslow,而选 pt-query-digest
mysqldumpslow 解析简单、无状态、不归一化 SQL,遇到带 IN 列表或不同 LIMIT 值的同构语句就拆成多条,统计失真。而 pt-query-digest:
- 自动参数化 SQL:
SELECT * FROM user WHERE id = 123和id = 456归为同一类 - 支持按时间范围切片:
pt-query-digest --since '2026-04-10 22:00:00' /var/log/mysql/slow.log - 能识别锁等待、扫描行数、返回行数等关键指标,报告里直接标出
Rows_examined异常高的语句 - 输出含“Query ID”,方便后续用
pt-query-advisor进一步给优化建议 - 安装后直接可用,无需额外依赖:Debian 系用
apt install percona-toolkit,CentOS 用yum install percona-toolkit
分析时最容易被忽略的三个细节
很多人跑完 pt-query-digest 就去看“最慢的 Top 10”,结果优化了半天没效果。真正关键的是:
-
Rows_examined远大于Rows_sent:说明 SQL 扫描大量无关行,大概率缺索引或索引失效(比如对字段用了函数) - 报告里出现大量
Using temporary; Using filesort:不是单条 SQL 慢,而是设计模式问题,得看是否能改分页逻辑或加覆盖索引 - 同一类 Query ID 的
Count极高(比如 10w+),但平均Exec time只有几毫秒:说明是高频轻量查询,瓶颈可能在连接池或网络,而不是 SQL 本身
日志分析不是找“最慢的一条”,而是找“影响面最大的一类”。











