大促后慢查询优化清单的落地执行,核心不是拿到一份SQL列表,而是把排查、分类、修复、回归这四个动作固化成团队的标准操作流程。 换句话说,大促结束并不意味着性能问题消失,真正的战场是从慢查询日志导出的那一刻才开始的。
慢查询优化从哪几个方面入手
大促后的慢查询,按照影响面可以分成五类:单条SQL执行时间过长、单个服务接口内部SQL调用过多、锁等待和死锁、索引失效引发的全表扫描、以及批量任务造成的资源争抢,很多团队习惯一上来就抓最长SQL,但这往往会漏掉“总量不大但拖垮整体”的问题。
一份可执行的大促后慢查询优化清单,应该回答四个维度的问题:
- 时间维度:慢查询集中在哪个时段?是促销峰值后延还是凌晨批量任务?
- 资源维度:CPU、IOPS、连接数是否被打满?慢查询是原因还是结果?
- 代码维度:慢SQL对应的业务代码有没有可以合并或裁剪的冗余查询?
- 数据维度:表中数据量增长了多少?索引基数是否仍然合理?
想快速确定优先级,可以按“影响用户数 × 出错频率”排序,影响登录、下单、支付的慢查询永远排在第一位,报表导出和后台统计可以放后面。
业内专家指出,大促后慢查询的黄金修复窗口是活动结束后72小时,超过这个期限,业务数据快速变化,重现和验证的成本都会升高。
大促后数据库慢查询排查步骤
这个环节是整个清单的核心,也是很多团队最容易卡住的地方,因为慢查询日志导出来以后,往往一眼看不到重点。
第一步:确认慢查询日志已经打开
如果在活动期间没开日志,大促后的排查就只能靠监控和猜测,MySQL实例开启慢查询的常用路径是:
- 临时开启:
SET GLOBAL slow_query_log = ON; - 设置阈值:
代表超过1秒记录SET GLOBAL long_query_time = 1;
- 查看日志位置:
SHOW VARIABLES LIKE 'slow_query_log_file';
建议大促期间把阈值临时调到 5秒,大促后调回 1秒或2秒,相比平时,大促后的流量曲线完全不同,阈值太松会漏掉关键慢SQL,太紧会导致日志量爆炸。
第二步:用工具对日志做初步分类
直接打开慢查询日志人工翻是低效的,常见的MySQL慢查询日志分析工具有三类,各有适用场景:
| 工具 | 优势 | 局限 |
|---|---|---|
| mysqldumpslow | MySQL自带,用法简单 | 只做汇总排序,不能看执行计划关联 |
| pt-query-digest | 支持按指纹聚合,输出报告详细 | 需要单独安装Percona工具包 |
| 云监控自带分析 | 免运维,可视化好 | 有些云厂商只保留部分采样 |
行业共识认为,先用自带的mysqldumpslow快速定位TopSQL,再用pt-query-digest做深度分析,是把排查时间压缩到最短的组合。
第三步:按执行次数和耗时排序
把日志里的SQL按“总执行时间 = 平均耗时 × 执行次数”排序,高执行次数低耗时的SQL,往往比低次数高耗时的SQL更值得优先处理,比如一个耗时50毫秒但每秒执行100次的SQL,实际占用的资源远高于一个耗时2秒但一天只跑一次的报表查询。
第四步:用EXPLAIN看执行计划
对TopSQL逐一执行EXPLAIN,重点看三个字段:
- type:是否出现
ALL全表扫描 - rows:预估扫描行数与实际返回行数的比例是否悬殊
- Extra:是否出现
Using filesort或Using temporary
这一步要把慢SQL的文本、执行计划、对应业务接口、最近一次变更记录一起保存,没有上下文信息的慢SQL清单,几天后就没人知道当初为什么改了。
把清单落地的具体姿势
拿到的优化清单要真正落地,靠的不是一次性修复,而是把动作固化到日常流程里,这里分享几个经过验证的做法。
建一个简单的巡检脚本
脚本不复杂,重点是把重复动作自动化,一个最小可用的巡检脚本至少包含:
- 抓取最近一小时的慢查询日志
- 按执行次数排序输出前10条
- 检查当前活跃连接数是否超过阈值的80%
- 将结果写入独立表或发到群机器人
这样每天早上打开电脑,扫一眼脚本输出就能判断当天有没有需要处理的慢SQL,对没有专职DBA的小团队来说,这比任何监控大屏都实在。
把优化项变成上线检查项
大促后排查出的慢SQL,修复后要防止下个版本改回来,具体做法是,在代码评审检查单里增加两条:
- 本次变更是否涉及核心表的查询条件变化?
- 是否已在测试环境执行过慢查询验证?
有人会觉得这小题大做,但很多慢查询之所以反复,就是因为代码评审时没人关心SQL执行计划。
大促后三天的复盘节奏
建议把复盘拆成三次短会,而不是一次长会:
- 第一天:只确认最严重的慢SQL是否恢复,更新清单状态
- 第二天:批量处理中期优化项,例如冗余索引、查询重写
- 第三天:归档所有慢SQL样例和解决方案,补充到团队的运维手册
时间控制在三十分钟以内,目的是让清单有明确节奏,而不是放在文档里吃灰。
常见慢查询场景的优化动作
一份电商网站大促后SQL优化方案,通常会覆盖下面几类高频场景,我们挑三个典型的说一说。
订单列表分页越翻越慢
深分页是典型问题。LIMIT 10000, 20 这种写法会扫描前10000行再丢弃,常见解法是改成基于游标的分页:
WHERE id > 上次最后一条ID ORDER BY id LIMIT 20,如果必须用普通分页,可以限制最大翻页深度,超出后提示用户缩小查询范围。
商品详情页聚合查询卡顿
大促后商品详情页经常要一次性查出库存、评价数、促销标签、同类推荐,这类查询的慢往往不是因为一条SQL,而是接口里反复查询了多次,优化手法是把多次小查询合并成一次大查询,或者把聚合结果提前缓存到Redis。
库存扣减的锁等待
库存扣减并发量高,行锁竞争不可避免,如果把“查询库存判断库存更新库存”拆成了三条SQL,锁等待时间会明显拉长,比较通用的做法是使用一条原子更新:UPDATE sku_stock SET stock = stock - ? WHERE sku_id = ? AND stock >= ?,让判断和扣减在数据库端一次完成。
华东某电商团队在应用上述方案后,虽然库存接口耗时没有明显下降,但促销期间的锁等待时间大幅缩短,这就是清单落地带来的实际收益。
关于大促后慢查询优化清单的常见问题
没有DBA的小团队如何落地大促后数据库慢查询排查步骤?
先租一个便宜的云MySQL实例,打开慢查询日志,然后用mysqldumpslow做每日汇总,重点看执行量最大的前五条SQL,晚上花半小时处理,这样坚持一个季度,团队对慢查询的敏感度会有明显提升。
MySQL慢查询日志分析工具怎么选?
如果实例在云上,先用云厂商自带的慢查询分析,它能直接给出索引建议,如果自建MySQL,pt-query-digest是最全能的选项,但学习成本略高,单机小流量场景下,mysqldumpslow足够用。
大促后慢查询优化清单多久能见效?
大多数情况下,第一轮修复后在第二个业务高峰就能看到效果,因为大促后前72小时的业务规律仍接近促销状态,此时验证优化效果最准确,换句话说,慢查询清单的终点不是消除所有慢SQL,而是让每条慢SQL都有明确的处理时限。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/636335.html





