4. MySQL 慢查询排查工具链

在报表导出服务中,慢查询是导致接口超时、Redis 热点堆积的根源之一。本节系统讲解三个核心排查工具:EXPLAIN 执行计划、pt-query-digest 慢查询日志分析、Performance Schema,并给出它们在报表导出场景下的联动使用策略。

排查原则:先通过 pt-query-digest 定位高频慢 SQL,再用 EXPLAIN 分析单条 SQL 的执行计划,最后用 Performance Schema 确认锁等待、IO 和索引使用细节。

4.1 EXPLAIN 执行计划分析

EXPLAIN 是 MySQL 提供的查询优化器执行计划查看命令。在报表导出场景中,多表 JOIN、子查询、大范围扫描是常见性能瓶颈,EXPLAIN 能直接暴露这些风险。

4.1.1 基本用法

-- 在慢查询 SQL 前加 EXPLAIN
EXPLAIN SELECT
    o.order_id, o.amount, u.name
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE o.created_at BETWEEN '2025-01-01' AND '2025-01-31'
ORDER BY o.amount DESC
LIMIT 1000;

4.1.2 关键字段解读

字段 含义 报表导出场景常见问题
type 访问类型(ALL、index、range、ref、eq_ref、const) ALL 全表扫描 → 必须优化为 range 或 ref
key 实际使用的索引 NULL 表示未使用索引 → 检查 WHERE/JOIN 列索引
rows 预估扫描行数 超过 10 万行 → 考虑分区或分页优化
Extra 额外信息(Using filesort、Using temporary、Using index) Using filesort → 排序字段未索引;Using temporary → 临时表过大
filtered 过滤后剩余行数百分比 低于 10% → 索引选择性差,需调整索引
报表导出典型优化案例:某次导出月订单报表时,EXPLAIN 显示 type=ALL、rows=500 万、Extra=Using filesort。添加 (created_at, amount) 联合索引后,type 变为 range、rows 降至 2 万、Extra 消失,查询耗时从 12s 降至 0.3s。

4.2 慢查询日志分析工具:pt-query-digest

pt-query-digest 是 Percona Toolkit 中的慢查询日志分析利器。它能从大量慢查询日志中自动聚合出最耗时的 SQL 模板,并给出执行次数、总耗时、平均耗时、锁等待等统计指标。

4.2.1 启用慢查询日志

-- 临时启用(生产环境谨慎)
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;      -- 超过 1 秒记录
SET GLOBAL log_queries_not_using_indexes = ON;

-- 查看日志路径
SHOW VARIABLES LIKE 'slow_query_log_file';

4.2.2 使用 pt-query-digest 分析

# 分析慢查询日志,输出排名前 10 的查询
pt-query-digest /var/lib/mysql/slow.log --limit 10

# 输出到文件,便于后续对比
pt-query-digest /var/lib/mysql/slow.log > slow_report.txt

4.2.3 输出解读

指标 含义 报表导出关注阈值
Rank 按总耗时排序的排名 Top 5 必须优先优化
Response time 该 SQL 模板的总耗时及占比 占比超过 30% → 核心瓶颈
Calls 执行次数 高频 + 慢查询 → 热点 SQL
R/Call 平均每次执行耗时 超过 2s → 需要索引或改写
Lock 锁等待时间 超过 500ms → 检查锁冲突
注意:pt-query-digest 不会自动过滤业务低峰期的慢查询。建议配合 --since 和 --until 参数,只分析报表导出高峰时段(如整点、半点)的日志。

4.3 Performance Schema 的使用

Performance Schema 是 MySQL 5.7+ 内置的性能监控引擎,能提供语句级、阶段级、等待事件级的细粒度数据。在报表导出场景中,它比 EXPLAIN 更擅长诊断锁等待、IO 瓶颈、索引使用统计。

4.3.1 启用与配置

-- 检查是否启用
SHOW VARIABLES LIKE 'performance_schema';

-- 启用(需在 my.cnf 中配置后重启)
performance_schema = ON

-- 启用语句事件采集
UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME LIKE 'events_statements%';

-- 启用等待事件采集
UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME LIKE 'wait/io/%';

4.3.2 常用查询

-- 查询最近 10 条最耗时的 SQL
SELECT
    DIGEST_TEXT,
    COUNT_STAR AS exec_count,
    SUM_TIMER_WAIT / 1000000000 AS total_sec,
    AVG_TIMER_WAIT / 1000000000 AS avg_sec,
    SUM_LOCK_TIME / 1000000000 AS lock_sec
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;

-- 查询索引使用情况
SELECT
    OBJECT_SCHEMA,
    OBJECT_NAME,
    INDEX_NAME,
    COUNT_STAR AS access_count,
    SUM_TIMER_WAIT / 1000000000 AS total_sec
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE INDEX_NAME IS NOT NULL
ORDER BY total_sec DESC
LIMIT 10;

4.3.3 与 EXPLAIN 的对比

维度 EXPLAIN Performance Schema
数据来源 优化器预估 实际执行统计
锁等待 不提供 精确到微秒
IO 等待 不提供 按表/索引统计
历史趋势 单次快照 累计汇总,可对比
适用场景 单条 SQL 优化 全局性能基线 + 锁分析

4.4 工具联动流程

在报表导出服务中,三个工具按以下流程联动,形成闭环排查体系:

  1. 阶段一:全局扫描 — 使用 pt-query-digest 分析慢查询日志,定位 Top N 慢 SQL 模板。
  2. 阶段二:单条分析 — 对 Top SQL 执行 EXPLAIN,检查 type、key、rows、Extra 字段,确定索引缺失或扫描过大。
  3. 阶段三:深度诊断 — 使用 Performance Schema 确认锁等待时间、IO 压力、索引实际使用频率。
  4. 阶段四:验证优化 — 添加索引或改写 SQL 后,再次用 pt-query-digest 对比优化前后的响应时间变化。
实战建议:在报表导出服务中,建议将 pt-query-digest 配置为定时任务(每 30 分钟执行一次),自动生成慢查询报告并推送至告警群。Performance Schema 的 events_statements_summary_by_digest 表可以按小时快照,用于长期趋势分析。
MySQL 慢查询排查工具联动流程 阶段一:全局扫描 pt-query-digest 定位 Top N 慢 SQL 模板 阶段二:单条分析 EXPLAIN 检查 type/key/rows/Extra 阶段三:深度诊断 Performance Schema 锁等待 / IO / 索引统计 阶段四:验证优化 添加索引 / 改写 SQL 再次 pt-query-digest 对比耗时 未达标则回退 输出结果 优化后的 SQL 模板 + 耗时对比报告 💡 联动要点 • pt-query-digest 负责“找问题”,EXPLAIN 负责“看计划”,Performance Schema 负责“挖细节” • 优化后必须回测,避免索引新增导致其他查询变慢

4.5 报表导出场景实战案例

某报表导出服务在整点导出时频繁超时,通过上述工具链排查过程如下:

步骤 工具 发现 优化动作 效果
1 pt-query-digest Top 1 SQL 耗时占比 45%,平均 8.2s 定位到订单汇总查询 —
2 EXPLAIN type=ALL, rows=320 万, Extra=Using filesort 添加 (created_at, amount) 联合索引 rows 降至 1.2 万
3 Performance Schema 锁等待 1.2s,索引使用率仅 12% 拆分大事务,减少锁范围 锁等待降至 80ms
4 pt-query-digest 回测 平均耗时 8.2s → 0.4s 确认优化有效 导出超时率从 15% 降至 0.3%
关键结论:三个工具缺一不可。pt-query-digest 负责“找问题”,EXPLAIN 负责“看计划”,Performance Schema 负责“挖细节”。在报表导出服务中,建议将三者集成到自动化排查脚本中,实现慢查询的分钟级定位与优化。