大促后的慢SQL治理,核心原则是“先止血、再归档、最后建机制”,用短平快的索引和参数调整兜住峰值,再靠归档把历史包袱拆掉,才能避免下一个大促周期重复踩坑。
大促后数据库响应变慢怎么办:先分清三类慢SQL
大促结束后的第一周,往往是DBA最忙的时候,订单表、库存流水表、用户行为日志表,这些在峰值期被高频写入的大表,一旦流量回落,问题反而暴露得更彻底,不是你优化得不够,而是大促期间积累的“数据债务”开始集中讨债。
慢SQL的症状通常有三类,排查方向完全不同。
全表扫描型慢SQL:数据量增长导致执行计划失效
大促期间,订单明细表可能从几百万行涨到几千万行,查询条件明明走了索引,但统计信息还没跟上,优化器估算行数严重失真,于是放弃索引选择全表扫描,这类慢SQL的特征是:平时执行几十毫秒,大促后突然变成几秒,而且越跑越慢。
排查方法很直接:
- 用
EXPLAIN ANALYZE看执行计划,对比预估行数和实际行数 - 检查
information_schema.tables里的表行数增长情况 - 对高频大表执行
ANALYZE TABLE刷新统计信息
多数情况下,更新统计信息之后,执行计划会恢复正常,但如果大促期间表结构发生了在线DDL变更,还需要检查索引是否被重建过。
锁等待型慢SQL:批量任务和在线业务互相踩踏
大促后第二天,运营团队通常会跑批量对账、数据补录、报表汇总,这些任务一次扫几百万行,和在线业务的单行更新争抢行锁和间隙锁,表现特征是:单条SQL本身不慢,但大量SQL在Waiting for table metadata lock或Lock wait timeout exceeded上排队。
排查时看performance_schema里的等锁事件:
SELECT FROM performance_schema.events_waits_current WHERE event_name LIKE '%lock%'\G
这类慢SQL不能靠加索引解决,需要拆批和限流,把UPDATE拆成1000行一批,批与批之间加SLEEP(0.1),给在线业务让路。
索引选择性劣化型慢SQL:数据倾斜让索引失去意义
大促会产生一批“爆款订单”,某些用户的订单量占到全表的20%以上,查询条件包含user_id时,优化器发现走索引要回表访问大量行,干脆改走全表扫描,这是在数据分布剧烈变化后,统计信息和真实数据脱节的典型表现。
处理方式是重新采集统计信息,并把业务查询改为“用户ID+时间范围”联合条件,提升索引选择性。
慢SQL归档和清理:怎么在不影响业务的情况下瘦身
慢SQL归档,本质上是把在线表的历史数据搬走,让扫描的数据量降下来,这是治本的手段,但操作顺序错了容易出事故。
归档前先做数据分级
归档不是把数据删掉,而是把冷数据从在线表里挪出去,放进归档库或归档表,需要先确定一个时间边界,只保留最近6个月订单”,然后按create_time或者order_id做分区。
需要想清楚三个问题:
- 业务上,哪些历史数据还需要被在线查询?比如用户查一年前的订单。
- 合规上,交易流水类数据通常要求留存至少3年,归档库要能满足审计需求
- 技术路径上,是按月分区直接
TRUNCATE,还是逐批DELETE后定时清理
归档执行步骤
推荐用pt-archiver做在线归档,它对线上业务干扰最小,操作路径如下:
# 按主键分批归档,每批1000行,每批之间休息1秒 pt-archiver \ --source h=127.0.0.1,D=shop_db,t=orders \ --dest h=192.168.1.10,D=shop_archive,t=orders \ --where "create_time < '2026-01-01'" \ --limit 1000 \ --bulk-delete \ --sleep 1
归档过程中要盯三个指标:主库的Threads_running不超过10,从库的Seconds_Behind_Master不超过30秒,磁盘IO使用率不超过70%。
有经验的DBA会提醒,归档一定要避开业务高峰,选凌晨2点到5点执行,如果数据量特别大,拆成多个时间窗口分几天跑,不要幻想一晚全部搞定。
归档后的三条保命规矩
归档完成不代表事情结束,下面三条规矩能帮你避免后续踩坑。
- 归档后24小时内,对原表执行
ANALYZE TABLE更新统计信息,否则执行计划可能误判 - 归档数据要保留原始主键,去归档库反查数据时可以快速定位
- 应用层的查询SQL要增加强制时间范围,避免用户无意识地全表扫描历史数据
慢SQL优化方案怎么选:实时治理还是事后归档
不少团队纠结大促后是做SQL改写优化还是直接归档历史数据,这不是二选一的问题,而是两条并行路线。
实时治理解决的是“当前SQL写得不对”,归档解决的是“数据太多没法查得快”,二者消耗的资源不同,配合使用效果最好。
| 对比维度 | 实时治理 | 事后归档 |
|---|---|---|
| 见效速度 | 索引加完立即生效 | 数据迁移完成才生效 |
| 适用场景 | 单条SQL执行计划劣化 | 大表查询整体变慢 |
| 对业务影响 | 加索引期间有短暂锁表 | 归档期间IO资源占用高 |
| 长期效果 | 只解决当前问题 | 根治数据膨胀 |
| 人力成本 | 依赖DBA逐个分析 | 需要写脚本和定时任务 |
| 运维风险 | 索引冗余导致写入变慢 | 归档数据丢失或不同步 |
行业共识认为,大促后第一周优先做实时治理,把执行计划异常的SQL修一遍,快速止血,第二周开始做归档,把不需要在线的历史数据搬走,彻底降低扫描基数。
慢SQL归档工具怎么选:开源免费和商业付费的真实差异
归档工具的选型容易被轻视,但选错了后期维护成本很高。
开源的pt-archiver是目前应用最广的方案,免费,功能稳定,支持批量删除、归档到文件或另一张表,短板是单线程,大表归档速度有限,需要自己控制并发,好处是社区文档丰富,在国内各大技术社区都能搜到踩坑案例。
商业方案(如部分云厂商的DAS自动归档)操作简单,界面拖拽配置即可,自带限流和备份功能,但费用按数据量或实例数计费,成百上千万行的历史数据长期放在归档实例上,成本不低。
如果团队有专职DBA,开源方案更灵活,归档逻辑完全可控,如果运维人力紧张,商业方案的价格换来了省心,这笔账要自己算。
归档之后的防复发机制:把慢SQL关进笼子里
没有防复发机制,大促后治理完的慢SQL,下一个周期会换个马甲卷土重来,归档是治标,机制才是治本。
建立慢查询日志的全量留存
多数团队的慢查询日志保留7天就清理了,这是不对的,没有历史数据,你无法回溯大促前后的性能变化曲线,也无法验证优化措施是否有效。
推荐做法是:将slow_query_log输出到独立的日志表或对象存储,至少保留一个完整的大促周期(通常按季度算),日志表本身可以按月分区分区,查询时限定时间范围,这样当你复盘一个慢SQL时,能看出它是从哪次数据量增长后开始劣化的。
制定巡检SQL标准
每周定时跑一轮巡检脚本,检查以下维度的变化趋势:
- 单表数据量环比增幅是否超过预期
- 是否有新的全表扫描出现在Top SQL
- 索引使用率低下的索引数量是否增加
- 热点行的锁等待时间是否有上升趋势
巡检脚本的输出接入告警,一旦某项指标触发阈值,自动创建工单推给值班DBA,而不是等人反馈卡顿后才去排查。
归档策略要写进大促复盘文档
每次大促结束后的复盘会,不要只聊带宽和容量,把慢SQL的治理和归档单独作为一个议题,统计大促期间共产生多少条慢SQL,按表维度聚合,找出哪些表是慢SQL高发源,把归档时间点提前到下次大促前完成,这样大促时的性能基线和日常保持一致,不会被历史数据拖后腿。
大促后慢SQL集中治理有哪些常见坑
归档和治理过程中,有四个高频坑值得单独拿出来讲,都是实际生产环境中反复出现的问题。
坑一:把归档当成DELETE直接执行
有人为了省事,直接对线上表执行大范围DELETE FROM orders WHERE create_time < '2026-01-01',单条DELETE会积累大量undo log,导致主从延迟飙升,甚至把binlog撑爆,正确做法是分批删除,或者用分区表TRUNCATE分区,不产生undo log。
坑二:归档后忘了处理归档库的性能
数据搬走了,在线库变快了,但归档库成了新的瓶颈,查询历史订单时,客户体验照样慢,投诉电话一样打进来,归档库同样需要建索引、做分区,查询语言也要针对归档场景单独测试。
坑三:忽略自增主键的二次利用
归档后,在线表的自增主键不会复用,新数据的自增ID继续增长,如果业务代码里写死了ID长度或依赖ID做分表路由,可能出现溢出风险,解决办法是把ID类型从INT升到BIGINT,或者在归档前预留足够的增长空间。
坑四:没有验证归档数据的完整性
归档任务跑完,只看了归档行数和源表剩余行数,没做抽样比对,等审计来查的时候,发现归档库缺了某天的数据,在两边都没法推卸责任的情况下,只能重新补导。归档完成后必须做校验:对比源表和归档库的行数、SUM关键金额字段、抽查时间边界数据,三条校验全部通过才算归档成功。
慢SQL从这里到归档,怎么闭环管理
慢SQL的治理不是一次性的DBA任务,需要形成闭环流程,建议按以下流程落地:
- 第一步,大促后第二天自动生成慢SQL报表,按执行次数和总耗时排序
- 第二步,对有索引调整空间的SQL直接优化,记录变更前后耗时对比
- 第三步,对超大表的访问量大但数据量太旧的情况,打标为待归档任务
- 第四步,归档任务排期执行,完成后自动校验数据完整性
- 第五步,将归档前后的SQL性能报告合并归档到慢查询日志库,作为下个周期的优化基线
闭环流程跑完一个周期后,你会发现慢SQL的集中爆发数量会逐渐收敛,大促后的数据库维护不再是一年两次的抢险,而是按计划推进的例行化运维。
大促后慢SQL集中爆发该怎么排查?
按顺序做三步:先看监控面板确认是CPU瓶颈还是锁等待瓶颈,再用mysqldumpslow或pt-query-digest聚合慢查询日志,找出Top N慢SQL,最后对每一条慢SQL执行EXPLAIN,按文中的三类症状分类处理。
慢SQL归档后,历史数据还能不能正常查询业务?
可以查,归档数据通常会放到独立的归档库或归档表,业务侧通过统一的查询入口访问,比如在SQL外层加一层视图,根据时间范围路由到在线库或归档库,查询体验上没有感知差异,只是历史数据的响应时间会比在线数据略高,如果历史订单查询非常频繁,可以对归档库做读写分离,用从库承担历史查询流量。
大促后数据库优化人力不够,靠工具自动优化靠谱吗?
工具可以完成慢SQL发现和索引建议的自动化分析,规则引擎会告诉你某个SQL缺了哪类索引,这是可靠的第一步。但工具无法理解业务语义,比如一个查询就是用来做后台报表的,即使全表扫描也不影响核心链路,工具却会把它标记为高风险,最终的决定判断要由熟悉业务的DBA或资深开发来做,工具定位是辅助分析,不等同于替代人力,把工具的自动建议用于初步筛查、把人工判断用于最终执行,才是投入产出最合理的组合。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/772682.html


