4、慢查询定位:开启慢查询日志、pt-query-digest工具使用、常见慢SQL模式识别

在批次追溯数据驱动的采购计划优先级排序场景中,SQL 查询的响应时间直接影响排序算法的执行效率。本章聚焦于如何系统性地定位慢查询,涵盖 MySQL 慢查询日志的开启与配置、专业分析工具 pt-query-digest 的使用方法,以及批次追溯场景中常见的慢 SQL 模式识别。

4.1 开启慢查询日志

慢查询日志是 MySQL 提供的原生性能诊断工具,用于记录执行时间超过指定阈值的 SQL 语句。在批次追溯系统中,建议在生产环境谨慎开启,并设置合理的阈值以避免日志文件过快增长。

4.1.1 动态参数配置

以下 SQL 语句可在 MySQL 客户端中动态启用慢查询日志,无需重启数据库实例:

-- 开启慢查询日志
SET GLOBAL slow_query_log = ON;

-- 设置慢查询阈值(单位:秒),建议初始设为 1 秒
SET GLOBAL long_query_time = 1;

-- 指定日志文件路径
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow_query.log';

-- 记录未使用索引的查询(便于发现全表扫描)
SET GLOBAL log_queries_not_using_indexes = ON;

4.1.2 持久化配置(my.cnf)

若需重启后配置依然生效,需在 MySQL 配置文件 my.cnf 的 [mysqld] 段中添加以下参数:

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow_query.log
long_query_time = 1
log_queries_not_using_indexes = 1
生产环境建议: 在批次追溯高并发时段,建议将 long_query_time 设置为 2 秒,避免日志量过大;在性能压测或调优阶段,可降至 0.5 秒以捕获更多细节。

4.2 pt-query-digest 工具使用

pt-query-digest 是 Percona Toolkit 中的核心分析工具,能够对慢查询日志进行聚合、排序和统计,快速定位最耗时的 SQL 模式。相比直接查看日志文件,pt-query-digest 提供了结构化的报告,便于识别性能瓶颈。

4.2.1 安装与基本用法

在 CentOS / Ubuntu 系统中安装 Percona Toolkit:

# CentOS / RHEL
yum install percona-toolkit

# Ubuntu / Debian
apt-get install percona-toolkit

分析慢查询日志并输出到终端:

pt-query-digest /var/log/mysql/slow_query.log

将分析结果保存到文件以便后续审查:

pt-query-digest /var/log/mysql/slow_query.log > slow_query_report.txt

4.2.2 报告解读要点

pt-query-digest 报告主要包含以下关键部分:

报告段落 内容说明 调优关注点
Overall 总查询数、总耗时、唯一查询指纹数 总耗时过高说明系统负载异常
Profile 按响应时间降序排列的查询指纹列表 重点关注 Rank 1-5 的查询指纹
Query 详情 单个查询指纹的响应时间分布、执行计划示例 查看 pct 列,耗时占比超过 20% 的查询必须优化
Tables 涉及的表及其访问模式 全表扫描、临时表、文件排序等标记
关键指标: 在批次追溯排序场景中,若某个查询指纹的 Response time ratio 超过 30%,且涉及批次库存表或采购计划明细表,应优先进行索引优化或 SQL 改写。

4.3 常见慢 SQL 模式识别

结合批次追溯数据的特点,以下四种慢 SQL 模式在采购计划优先级排序中频繁出现,需重点识别与治理。

4.3.1 模式一:全表扫描 + 大表关联

当批次追溯表(如 batch_trace)与采购计划表(如 procurement_plan)关联时,若未使用索引,MySQL 将执行全表扫描,导致响应时间随数据量线性增长。

-- 慢查询示例:未使用索引的全表关联
SELECT p.plan_id, p.priority_score, b.batch_status
FROM procurement_plan p
LEFT JOIN batch_trace b ON p.batch_no = b.batch_no
WHERE p.plan_date >= '2025-01-01';

识别特征: pt-query-digest 报告中出现 full scan 标记,且 Rows examine 远大于 Rows sent。

4.3.2 模式二:ORDER BY 未走索引导致文件排序

优先级排序通常需要按 priority_score 降序排列,若该字段未建立索引,MySQL 会使用 filesort 算法,在内存或磁盘中排序,消耗大量 CPU 和 IO。

-- 慢查询示例:ORDER BY 导致文件排序
SELECT plan_id, batch_no, priority_score
FROM procurement_plan
WHERE status = 'PENDING'
ORDER BY priority_score DESC
LIMIT 100;

识别特征: EXPLAIN 输出中 Extra 列包含 Using filesort。

4.3.3 模式三:子查询嵌套过深

批次追溯数据查询中,开发人员常使用多层子查询实现业务逻辑,导致 MySQL 生成低效的执行计划,产生派生表(Derived table)扫描。

-- 慢查询示例:三层子查询嵌套
SELECT plan_id, priority_score
FROM procurement_plan
WHERE batch_no IN (
    SELECT batch_no FROM batch_trace
    WHERE trace_id IN (
        SELECT trace_id FROM trace_detail
        WHERE material_code = 'MAT-001'
    )
);

识别特征: EXPLAIN 中 select_type 为 DEPENDENT SUBQUERY 或 DERIVED,且 rows 估算值极大。

4.3.4 模式四:函数包裹索引列导致索引失效

在 WHERE 条件中对索引列使用函数(如 DATE()、SUBSTRING()),会使 MySQL 无法使用索引,转而执行全表扫描。

-- 慢查询示例:DATE() 函数导致索引失效
SELECT plan_id, priority_score
FROM procurement_plan
WHERE DATE(create_time) = '2025-04-01';

优化写法: 改为范围查询以利用索引:

SELECT plan_id, priority_score
FROM procurement_plan
WHERE create_time >= '2025-04-01 00:00:00'
  AND create_time < '2025-04-02 00:00:00';
避坑提示: 在批次追溯场景中,batch_no 字段常被设计为 VARCHAR 类型,若查询时传入数值类型,MySQL 会发生隐式类型转换,同样会导致索引失效。请确保应用层传入的参数类型与字段类型一致。

4.4 慢查询定位流程总览

以下 SVG 图展示了从开启慢查询日志到定位根因的完整流程,帮助团队建立标准化的性能诊断步骤。

慢查询定位流程总览 开启慢查询日志 收集慢查询日志 pt-query-digest 分析 识别慢 SQL 模式 EXPLAIN 执行计划验证 索引优化 / SQL 改写 关键检查点 • long_query_time 阈值设置 • 日志文件磁盘空间监控 • 生产环境避免开启所有查询 常见慢 SQL 模式 • 全表扫描 + 大表关联 • ORDER BY 文件排序 • 子查询嵌套过深 • 函数导致索引失效

4.5 慢查询模式对比速查表

以下表格汇总了四种常见慢 SQL 模式的识别特征、影响范围及推荐优化策略,便于团队在性能调优时快速对照。

慢 SQL 模式 EXPLAIN 特征 典型影响 推荐优化策略
全表扫描 + 大表关联 type: ALL,Extra: Using where 响应时间随数据量线性增长 为关联字段(如 batch_no)添加索引
ORDER BY 文件排序 Extra: Using filesort CPU 和内存消耗高,排序延迟 为排序字段(如 priority_score)建立索引
子查询嵌套过深 select_type: DEPENDENT SUBQUERY 逐行执行子查询,N+1 问题 改写为 JOIN 或使用临时表
函数导致索引失效 type: ALL,possible_keys: NULL 索引列无法使用,全表扫描 将函数操作移至应用层,或改为范围查询
实践建议: 在批次追溯排序场景中,建议将 pt-query-digest 分析纳入日常发布流程。每次上线前,对比慢查询报告中的 Response time ratio 变化,确保新功能未引入新的慢 SQL 模式。