mysql慢查询日志如何分析_mysql日志优化方法

来源:这里教程网 时间:2026-02-28 20:48:07 作者:

怎么确认慢查询日志是否真的在记录

很多情况下你以为开启了慢查询,其实

slow_query_log
是 OFF 状态,或者
long_query_time
被设得太高(比如 10 秒),导致日常耗时 300ms 的查询根本不会被捕获。

执行这条命令看真实状态:

SHOW VARIABLES LIKE 'slow_query_log';<br>SHOW VARIABLES LIKE 'long_query_time';<br>SHOW VARIABLES LIKE 'log_output';

log_output
值要是
FILE
才会写入文件;如果是
TABLE
,就得查
mysql.slow_log
表——但默认该表是 CSV 引擎,不支持索引,查起来反而慢,不推荐生产环境用。

线上建议设
long_query_time = 1
(秒),高并发场景可压到
0.5
确保
slow_query_log = ON
log_output = FILE
检查
slow_query_log_file
路径是否有写权限,MySQL 进程能否触达

用 pt-query-digest 快速定位瓶颈 SQL

原生日志文本杂乱,直接

grep
awk
效率低、易漏关键信息。Percona Toolkit 的
pt-query-digest
是事实标准工具,它能聚合、排序、统计,并标出锁等待、全表扫描、临时表等风险点。

基本用法:

pt-query-digest /var/lib/mysql/slow.log --limit 10

常用关键参数:

--filter
:过滤掉特定用户或库,比如
'$event->{db} =~ m/^test/'
--since
--until
:按时间范围切片分析
--review
+
--review-history
:把结果存进数据库做趋势对比
--no-report
可跳过汇总报告,只导出可疑语句供人工复核

注意:

pt-query-digest
默认按响应时间排序,但真正拖垮系统的往往不是“最慢那条”,而是“执行频次最高+平均耗时中等”的 SQL,记得看
Count
Exec time
的乘积列(即总耗时占比)。

哪些 SQL 特征必须人工介入优化

pt-query-digest
能标出问题,但不会自动改 SQL 或建索引。以下特征出现时,必须立刻人工跟进:

Rows_examined
远大于
Rows_sent
(比如扫 10 万行只返回 1 行),大概率缺索引或索引失效
语句含
Using filesort
Using temporary
(在
EXPLAIN
结果里),说明排序/分组没走索引
出现
SELECT *
+
LIMIT
大偏移(如
LIMIT 10000,20
),分页深度越大越慢
WHERE 条件用了函数(如
WHERE DATE(create_time) = '2024-01-01'
),导致索引无法下推

验证索引是否生效,别只看

EXPLAIN
type
字段,重点看
key
(实际用了哪个索引)、
rows
(预估扫描行数)、
Extra
(有没有
Using index
覆盖索引)。

日志本身也会成为性能负担

开启慢查询日志不是“一劳永逸”,尤其在高 QPS 场景下,频繁写磁盘可能拖慢 MySQL 吞吐。几个容易被忽略的细节:

日志文件不要放在系统盘或和
datadir
同一物理磁盘,避免 IO 冲突
定期轮转(用
mysqladmin flush-logs
或 logrotate),否则单个文件过大,
pt-query-digest
解析会卡住
如果只是临时排查,用
SET GLOBAL slow_query_log = ON
动态开启,完事后关掉,比永久配置更安全
MySQL 8.0+ 支持
log_slow_extra
,能记录更多上下文(如客户端 IP、SQL 模板 hash),但会加重日志体积,按需开启

最常被跳过的一步:分析完慢日志后,没同步更新监控项。比如发现某类

UPDATE ... WHERE status=0
很慢,就该在 Prometheus + Grafana 里加一条告警:当该语句平均耗时 >500ms 持续 3 分钟就通知。

相关推荐