数据库

MySQL 慢查询分析方法

2026-08-06 #性能优化#MySQL#SQL

把慢日志、执行计划和数据分布结合起来定位瓶颈。

核心思路

先确认慢是偶发还是稳定,再查看扫描行数、返回行数和锁等待。避免在索引列上做隐式类型转换或函数运算。

落地步骤

优化目标不只是单次查询更快,也要降低并发下的资源消耗。调整 SQL 或索引后应回归写入性能与边界结果。

验证清单

实施后不要只确认“能运行”,还应检查错误率、延迟、资源占用和异常路径。把验证命令、预期结果和回滚方式写进变更记录,后续维护会轻松很多。

小结

好的工程实践不是堆叠工具,而是用清晰边界、可观察结果和可逆变更降低长期成本。先解决最重要的问题,再逐步自动化。

可执行实践

启用受控慢日志并按总耗时、平均耗时和扫描行数排序。使用 EXPLAIN ANALYZE 检查访问类型、实际行数、回表与排序,确认字段类型避免隐式转换。

验证与退出条件

在副本或压测环境验证新索引对写入和磁盘的影响。线上变更观察锁等待、Buffer Pool 和复制延迟,保留旧索引到稳定期结束。

实践场景

以“处理高峰期出现的 MySQL 慢查询”为例。实施前先保存当前版本、配置和关键指标基线,写明成功条件与停止条件;涉及生产数据或外部写入时,先在隔离环境验证。

分步实施

从慢日志确认指纹与频率,用 EXPLAIN ANALYZE 检查访问路径;先减少扫描与返回列,再考虑索引和分页方式。每完成一步都记录可观察结果,不把命令返回零等同于业务正确。

故障演练

用接近生产的数据量测试选择性差、参数极端和锁等待,避免小表上优化得出错误结论。演练应使用可清理的测试数据,并验证告警、日志和恢复路径,而不只是确认系统最终又能访问。

观测与回滚

观察 P95、rows examined、锁等待和写放大;回滚索引或 SQL 前确认兼容旧应用版本。变更单中应写清负责人、观察窗口、阈值和回滚触发器,避免故障发生后再临时争论。

完成后把使用的版本、关键命令、观测窗口和结果写入变更记录。没有验证证据的“已完成”不能作为上线结论。

第二轮实践复核

可复用交付物: 慢查询指纹、真实执行计划和数据分布说明。复用时先固定软件版本、依赖锁文件、测试数据规模和运行环境;文章中的命令包含占位符,必须替换成自己的非生产目标后再执行。

最低验证: EXPLAIN ANALYZE SELECT ...;

执行记录要保存命令、退出码、关键输出、观察窗口和回滚结果。若验证会产生写入,先使用隔离环境或 dry-run;任何失败都不能通过扩大权限、关闭校验或跳过测试来“解决”。

完整实战:订单列表从 1.8 秒降到预算内

查询按用户、状态和时间筛选并倒序分页:

1
2
3
4
5
6
7
SELECT id, status, total_cent, created_at
FROM orders
WHERE tenant_id = ?
AND status = ?
AND created_at < ?
ORDER BY created_at DESC, id DESC
LIMIT 50;

候选复合索引是 (tenant_id, status, created_at, id),等值条件在前、范围和排序字段在后。但索引设计不能只看这一条查询:需要统计字段选择性、其他常用路径、写入放大和索引体积,再在同数据分布的环境验证执行计划。

1
2
3
4
5
6
7
8
EXPLAIN ANALYZE
SELECT id, status, total_cent, created_at
FROM orders
WHERE tenant_id = 42
AND status = 'paid'
AND created_at < '2026-08-22 00:00:00'
ORDER BY created_at DESC, id DESC
LIMIT 50;

关注实际扫描行数、循环次数、排序/临时表、估算与实际偏差,而不是只看到“使用了某个索引”就结束。若返回 50 行却扫描几十万行,索引或谓词仍有问题。

安全变更顺序

阶段 动作 退出条件
基线 保存查询指纹、P95、调用量、计划 能稳定复现
候选 在影子数据创建索引 计划改善且写入成本可接受
灰度 低峰在线变更,限制资源 复制延迟、锁等待未越线
观察 对比读写延迟和慢查询 完整业务周期无回退
清理 评估重复/无用索引 有使用证据和回滚窗口

深分页不要无限使用 OFFSET,它仍需扫描并丢弃前面的行。使用稳定排序的 seek/cursor 分页,并包含并列字段 id。应用层同时限制最大页大小和时间范围,避免一个合法请求变成全表工作。

故障演练包括冷缓存、热点租户、统计信息过期、并发写入和复制库延迟。上线后观察查询 P95/P99、扫描/返回比、buffer pool 命中、锁等待、复制延迟与写入耗时。出现回归时先切回旧查询路径;删除索引是单独的后续动作,不要和应用回滚绑在一起。

一手资料

资料与版本边界复核日期:2026-08-22。工具行为可能演进,实施前以锁定版本对应的官方文档为准。

评论
分享

评论