怎么确认慢查询日志是否真的在记录
很多情况下你以为开启了慢查询,其实
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 分钟就通知。
