大促后的慢查询优化不是技术选修课,而是决定系统能否平稳承接流量回落的必修课,核心结论:将慢查询优化清单落地为可执行的巡检脚本、分级响应机制和复盘模板,能降低后续大促期间数据库故障概率的三成以上。
慢查询清单落地前的现状盘点
大促结束后的第一周,绝大多数团队会陷入两种极端:一种是马上投入到新功能开发,把大促期间积累的慢查询日志束之高阁;另一种是全员扑上去逐个优化SQL,但缺少优先级和验收标准,忙了两周却发现核心问题依然存在。
行业共识认为,慢查询优化清单的落地执行必须遵循“先量化、再分级、后治理”的路径,先把大促期间的慢查询日志、监控指标、告警记录统一汇总,按照响应时间、执行频率、影响用户数三个维度打分排序,没有这一步,后续的所有动作都是盲打。
具体的操作路径如下。
- 从云数据库控制台导出慢查询日志,时间范围覆盖大促前三天至大促结束后一天
- 拉取数据库审计记录,筛选出执行次数超过100次且平均耗时超过200ms的SQL模板
- 对比大促前后的监控曲线,标记出CPU使用率、连接数、锁等待时间明显异常的时段
- 将上述数据汇总到统一的表格中,字段包括SQL文本、执行计划、平均耗时、最大耗时、出现次数、涉及的表与索引
慢查询分级的执行标准
慢查询清单不是一份平铺直叙的列表,需要根据影响程度划分成P0、P1、P2三个级别,P0是指直接影响核心交易链路、导致用户操作失败或超时的SQL,比如下单接口的库存扣减、订单状态更新,P1是指对核心链路有性能损耗但尚不致命的SQL,比如商品列表页的筛选查询、用户订单列表的分页查询,P2是指后台管理端或非核心业务中的慢查询,不直接影响用户体验。
分级依据可以参照执行计划中的关键词和高频操作组合判断。
依据执行计划识别P0级别问题
P0级别的慢查询几乎都有共同特征。
- 全表扫描:在千万级数据量的表上出现type=ALL的访问类型,而where条件中明明有合适的索引
- 临时表与文件排序:Extra字段中出现Using temporary和Using filesort,且涉及多表join或order by
- 索引失效:对索引列使用了函数运算、隐式类型转换,或者使用了不等于、IS NULL等无法走索引的条件
- 锁等待严重:慢查询日志中的锁等待时间占比超过总耗时的30%,且同时伴有大量的死锁告警
当开发人员看到上述特征时,应当在半天内完成索引优化或SQL重写,并在大促后的首次压测中验证效果,行业经验表明,P0级别的慢查询如果拖延超过48小时不处理,下一个业务高峰很可能再次触发相同的故障。
针对P1和P2的批量优化策略
P1级别的慢查询通常分布在列表页和详情页,优化方式以覆盖索引、延迟关联和分页优化为主,P2级别的慢查询则集中在运营后台,可以安排在下个迭代周期统一处理,无需紧急停线上。
慢查询优化的三大实操手段
落地执行慢查询优化清单时,SQL层面的改写、索引层面的调整、架构层面的分流是三个核心抓手,三者不是选其一,而是按顺序递进:先改SQL,再调索引,最后考虑架构。
SQL改写:消除非必要的开销
SQL改写是成本最低、见效最快的优化方式,多数高危慢查询都源于以下几个习惯。
- 查询了不需要的列,比如
SELECT搭配多表join,实际只用到了其中两个字段 - 在where条件中对索引列使用
LIKE '%keyword%',导致全表扫描 - 使用
OR连接不同索引条件,迫使优化器放弃索引合并 - 对索引列进行
DATE_FORMAT(create_time, '%Y-%m-%d')这类函数操作后,再与字符串比较
改写示例:
原SQL:SELECT FROM orders WHERE DATE_FORMAT(create_time, '%Y-%m-%d') = '2026-06-18' AND status = 1
优化后:SELECT order_id, user_id, amount FROM orders WHERE create_time >= '2026-06-18 00:00:00' AND create_time < '2026-06-19 00:00:00' AND status = 1
这个改写去掉了全表扫描,并减少了返回的列数据,效果是响应时间从1.2秒降到80毫秒左右。
索引调整:以执行计划为准
很多人优化慢查询时习惯先凭经验加索引,这种做法往往带来副作用,正确的步骤是先拿到慢查询的执行计划,用EXPLAIN查看当前索引使用情况,再决定是新增索引还是修改已有索引。
操作路径如下。
- 执行
EXPLAIN SELECT ...查看type、possible_keys、key、rows、Extra列 - 如果key为NULL,说明没有可用索引,需结合where条件中的等值列和排序列创建联合索引
- 如果rows估算扫描行数与实际表行数差距过大,考虑更新表的统计信息
- 如果Extra中出现Using filesort,检查排序字段是否包含在索引中
注意索引数量不是越多越好。 一个表上的索引数量控制在5个以内比较合适,索引过多会导致写放大,大促期间的高并发写入会把索引维护的开销放大成新的瓶颈,业内专家指出,覆盖索引和联合索引的字段顺序应当遵循“等值字段在前、排序字段在后”的原则。
架构分流:解决数据库单点压力
当SQL改写和索引调整完成后,若仍有部分慢查询因为数据量级实在过大而无法根治,可以考虑做分库分表或者引入只读副本,大促后的清单落地中,应当把这类需要架构改造的任务单独梳理成一项,与日常的SQL优化区分开,评估改造周期和上线风险。
判断是否需要分流的依据:
- 单表数据量超过2000万行且持续高速增长
- 慢查询集中在少数几张核心表,且无法通过索引优化根治
- 读写不均衡明显,只读流量占总流量的八成以上
慢查询优化清单的巡检工具与脚本
清单落地不能依靠人肉盯日志,应该把巡检规则沉淀为脚本或工具,之后每次大促结束后直接复用。
建立每日巡检脚本
推荐使用Shell脚本配合MySQL的information_schema库进行自动巡检,每天凌晨生成一份慢查询统计报告。
示例脚本逻辑如下。
#!/bin/bash
# 读取数据库的慢查询日志并统计前20条耗时最长的SQL模板
# 需要提前开启慢查询日志并设置long_query_time=1
MYSQL_CMD="mysql -hlocalhost -uroot -p -e"
$MYSQL_CMD "SELECT SUBSTRING_INDEX(sql_text, '\\n', 1) AS sql_template,
COUNT() AS cnt,
ROUND(AVG(query_time), 2) AS avg_time,
ROUND(MAX(query_time), 2) AS max_time
FROM mysql.slow_log
WHERE start_time > DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY sql_template
ORDER BY avg_time DESC
LIMIT 20;"
巡检结果可以对接钉钉或企业微信机器人通知,由DBA在早会上同步给研发团队。
使用Percona Toolkit分析慢日志
pt-query-digest是分析慢查询日志的常用工具,它能将大量杂乱日志自动归类为按“响应时间占比+执行次数”排序的报表。
pt-query-digest /var/log/mysql/mysql-slow.log > /tmp/slow_report_$(date +%Y%m%d).txt
拿到报表后只看三个内容:全局排名靠前的查询模式、每个模式的平均响应时间、最耗时的样例SQL,其余细节不用在巡检阶段纠结,进入专项优化再深入。
慢查询治理的复盘模板
大促后清单落地执行的最后一步是复盘,复盘不是例行公事,需要明确记录哪些措施有效、哪些措施无效,并形成下一轮大促的预习材料。
复盘模板的核心模块
- 背景记录:大促期间慢查询的总数、P0级别的数量、最长响应时间
- 优化动作清单:每条SQL的原始耗时、优化后耗时、耗时下降比例、采用的优化手段
- 回归验证结果:压测环境下的响应时间分布、CPU使用率变化、慢查询数量变化
- 遗留问题与排期:未根治的慢查询列表,标注入负责人和预计完成时间
- 新SQL审查规则更新:根据本次优化内容,补充代码评审中的SQL规范
形成SQL编写规范防止再犯
很多慢查询是研发人员在开发阶段没有意识到索引和数据量问题造成的,大促后的清单落地正好推动制度完善,将本次优化中的典型案例抽象成规则,禁止在where中使用函数包裹索引列”“分页查询禁止使用深偏移量”“join关联字段的类型必须一致”,纳入CI流水线中的SQL审核工具,从源头拦截高风险SQL。
大促后慢查询优化清单的常见问题
大促后慢查询日志保留多久合适?
至少保留一个完整的业务周期,建议保留最近三个月的慢查询日志,大促期间的特殊流量形态可能掩盖一些低频率高风险的查询,积累更长周期的日志才能在后续的小型活动中捕捉到问题,如果存储空间受限,可以归档到OSS等低成本存储中,并保留统计摘要表以便快速查询。
慢查询优化必须在大促结束后立即完成吗?
P0级别的慢查询应当在一周内完成优化和上线,P1级别的可以在两周内完成,P2级别的排入常规迭代,拖延的主要风险是,季节性流量波动或临时运营活动一旦启动,原有隐患会再次暴露,造成反复告警和紧急救火。
写完SQL优化方案后如何验证确实有效?
验证的步骤是先在生产环境的只读副本上执行EXPLAIN确认执行计划是否改变,然后在压测环境回放该SQL的高并发调用,检查平均响应时间和最大响应时间,不能用单次执行耗时作为唯一指标,要看并发场景下的表现,最后在业务低峰期灰度上线,观察监控面板中的慢查询数量和数据库负载变化。
慢查询优化清单的价值在于把大促期间的真实故障转化为可复用的治理经验,真正把清单落到脚本、落到规范、落到复盘文档中的团队,会在下一个流量高峰来临时发现数据库不再是最先崩溃的那一环。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/774079.html


