4. 慢查询日志分析:开启慢查询日志、使用 mysqldumpslow / pt-query-digest 分析、定位慢 SQL

在高并发评分通道中,数据库性能瓶颈往往源于未被发现的慢查询。慢查询日志是 MySQL 提供的最基础、最直接的性能诊断工具。本章将系统讲解如何正确开启慢查询日志,以及如何利用 mysqldumpslow 和 pt-query-digest 两款工具高效定位慢 SQL。

4.1 慢查询日志的开启与配置

慢查询日志记录执行时间超过指定阈值(long_query_time)的 SQL 语句。在生产环境中,建议谨慎开启,避免日志文件过大导致磁盘 I/O 压力。

配置项 默认值 推荐值(高并发场景) 说明
slow_query_log OFF ON 开启慢查询日志
slow_query_log_file 主机名-slow.log /var/log/mysql/slow-query.log 日志文件路径
long_query_time 10.000000 1.000000 或 0.500000 阈值(秒),评分通道建议 ≤1s
log_queries_not_using_indexes OFF ON 记录未使用索引的查询
log_slow_admin_statements OFF ON 记录慢管理语句(ALTER、ANALYZE 等)
min_examined_row_limit 0 1000 扫描行数超过此值才记录(过滤小表全表扫描)
配置示例(动态生效,无需重启):
SET GLOBAL slow_query_log = ON;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log';
SET GLOBAL long_query_time = 1;
SET GLOBAL log_queries_not_using_indexes = ON;
SET GLOBAL log_slow_admin_statements = ON;
SET GLOBAL min_examined_row_limit = 1000;
注意:在 MySQL 8.0+ 中,log_queries_not_using_indexes 已更名为 log_slow_extra,但旧名称仍兼容。建议同时监控磁盘空间,避免日志文件撑满数据盘。

4.2 慢查询日志分析工具对比

原始慢查询日志是纯文本格式,可读性差。业界主流使用 mysqldumpslow(MySQL 自带)和 pt-query-digest(Percona Toolkit)进行聚合分析。

特性 mysqldumpslow pt-query-digest
安装方式 MySQL 自带,无需额外安装 需安装 Percona Toolkit
聚合能力 按 SQL 指纹聚合,支持排序 按指纹聚合,支持多维排序、过滤
输出格式 文本表格 文本报告 / JSON / 树形图
查询时间统计 总时间、平均时间、最大时间 总时间、平均时间、中位数、95 百分位、标准差
锁等待分析 不直接支持 支持 Lock Time 统计
行数分析 支持 Rows_examined / Rows_sent 支持 Rows_examined / Rows_sent / Rows_affected
适用场景 快速查看 Top N 慢查询 深度分析、报表生成、自动化巡检

4.3 使用 mysqldumpslow 快速定位 Top SQL

mysqldumpslow 是 MySQL 自带的 Perl 脚本,位于 MySQL 安装目录的 bin/ 下。常用参数如下:

  • -s t:按查询总时间排序(默认)
  • -s at:按平均查询时间排序
  • -s c:按执行次数排序
  • -t N:只显示前 N 条
  • -g pattern:按正则过滤 SQL 文本
  • -a:不将数字抽象为 N,显示原始值
实战命令示例:
# 查看总耗时最长的前 10 条慢查询
mysqldumpslow -s t -t 10 /var/log/mysql/slow-query.log

# 查看平均耗时最长的前 5 条,并过滤包含 "score" 的表
mysqldumpslow -s at -t 5 -g "score" /var/log/mysql/slow-query.log

# 查看执行次数最多的前 3 条,保留原始数字
mysqldumpslow -s c -t 3 -a /var/log/mysql/slow-query.log

输出示例解读:

Count: 123  Time=2.34s (288s)  Lock=0.01s (1.23s)  Rows=1000.0 (123000)
  SELECT * FROM score_rank WHERE batch_id = N ORDER BY score DESC LIMIT N
  • Count:该 SQL 指纹被执行了 123 次
  • Time=2.34s (288s):平均耗时 2.34 秒,总耗时 288 秒
  • Lock=0.01s (1.23s):平均锁等待 0.01 秒,总锁等待 1.23 秒
  • Rows=1000.0 (123000):平均扫描/返回 1000 行,总计 123000 行

4.4 使用 pt-query-digest 深度分析

pt-query-digest 是 Percona Toolkit 的核心工具,功能远超 mysqldumpslow。它不仅能分析慢查询日志,还能分析通用日志、二进制日志、tcpdump 抓包文件。

安装 Percona Toolkit(CentOS / Ubuntu):
# CentOS
yum install percona-toolkit

# Ubuntu
apt-get install percona-toolkit

常用分析命令:

# 分析慢查询日志,输出到终端
pt-query-digest /var/log/mysql/slow-query.log

# 分析慢查询日志,输出到文件
pt-query-digest /var/log/mysql/slow-query.log > /tmp/slow_report.txt

# 分析最近 1 小时的慢查询(配合时间过滤)
pt-query-digest --since '2025-01-01 10:00:00' --until '2025-01-01 11:00:00' /var/log/mysql/slow-query.log

# 分析并只显示前 5 个最慢的查询指纹
pt-query-digest --limit 5 /var/log/mysql/slow-query.log

# 分析并输出 JSON 格式(便于程序处理)
pt-query-digest --output json /var/log/mysql/slow-query.log

4.5 慢查询定位流程与 SVG 分析图

以下 SVG 图展示了从开启日志到定位慢 SQL 的完整分析流程:

慢查询定位分析流程 1. 开启慢查询日志 2. 收集慢查询日志 3. mysqldumpslow 4. pt-query-digest 5. 定位 Top N 慢 SQL 6. EXPLAIN 分析 7. 索引优化 / SQL 改写 8. 验证优化效果 虚线表示循环迭代优化 直到慢查询消除或可接受

4.6 定位慢 SQL 后的关键分析维度

当通过工具定位到具体的慢 SQL 后,需要从以下四个维度进行深度分析:

  1. 查询时间分布:查看平均时间、最大时间、95 百分位时间,判断是否存在偶发性的严重慢查询。
  2. 扫描行数与返回行数:如果 Rows_examined 远大于 Rows_sent,说明索引过滤性差,需要优化索引或改写 SQL。
  3. 锁等待时间:高锁等待通常意味着并发写冲突或行锁升级为表锁,需要检查事务隔离级别和索引使用。
  4. 查询频率:即使单次查询不慢,但高频执行也会累积大量耗时,这类 SQL 应优先考虑缓存或批量处理。
实战案例:某评分通道的 SELECT * FROM score_detail WHERE batch_id = ? AND user_id = ? ORDER BY create_time DESC LIMIT 1 在 mysqldumpslow 中显示总耗时排名第一。通过 pt-query-digest 进一步分析发现,该 SQL 平均扫描 50000 行但只返回 1 行。添加联合索引 (batch_id, user_id, create_time) 后,扫描行数降为 1 行,查询时间从 2.3 秒降至 0.003 秒。

4.7 慢查询日志的运维注意事项

  • 日志轮转:使用 logrotate 定期切割慢查询日志,避免单个文件过大。切割后执行 mysqladmin flush-logs 让 MySQL 重新打开日志文件。
  • 采样策略:高并发场景下,建议将 long_query_time 设置为 0.5~1 秒,并配合 min_examined_row_limit 过滤掉小表全表扫描的噪声。
  • 安全审计:慢查询日志可能包含敏感数据(如用户 ID、手机号),生产环境应限制日志文件的访问权限,并定期清理。
  • 自动化告警:结合 pt-query-digest 的 JSON 输出,编写脚本定时分析慢查询,当新增慢 SQL 或总耗时突增时触发告警。
避坑指南:不要在生产数据库上直接执行 pt-query-digest 分析,建议将慢查询日志拷贝到分析服务器或使用 --processlist 模式从从库采集。另外,mysqldumpslow 在 MySQL 8.0 中已标记为废弃,推荐逐步迁移到 pt-query-digest。