mysql大数据集删除缓慢如何优化_使用分批删除避免锁表

张开发
2026/6/1 19:29:31 15 分钟阅读
mysql大数据集删除缓慢如何优化_使用分批删除避免锁表
DELETE百万行卡死是因RR级别下全表扫描触发next-key lock全表锁定叠加binlog/undo log膨胀阻塞purge线程分批删须用ORDER BY单调字段锚定且WHERE条件必须命中联合索引(status,id)配合sleep避免主从延迟。DELETE 语句直接删百万行为什么卡死因为 MySQL 默认在可重复读RR隔离级别下DELETE 会为扫描到的每行加 next-key lock全表扫 全表锁。更糟的是大事务会拖长 binlog 和 undo log 生命周期阻塞 purge 线程进一步拖慢后续操作。现象执行 DELETE FROM t WHERE status 0 卡住SHOW PROCESSLIST 显示 Updating 状态持续数分钟本质不是“慢”是“锁冲突日志膨胀”双重阻塞哪怕加了 status 索引如果匹配行太多MySQL 仍可能放弃索引走全表扫描看 EXPLAIN 的 rows 和 type用 LIMIT 分批删但没加 ORDER BY 会漏删分批删不是加个 LIMIT 就完事。InnoDB 不保证无 ORDER BY 时的物理顺序同一批可能反复删同一组行跳过另一些——尤其在并发写入场景下。错误写法DELETE FROM t WHERE status 0 LIMIT 1000循环执行→ 可能永远删不完正确做法锚定一个单调递增字段如 id每次删 id last_id AND status 0 的最小 1000 行必须加 ORDER BY id LIMIT 1000否则优化器可能改变扫描顺序示例DELETE FROM t WHERE status 0 AND id 12345 ORDER BY id LIMIT 1000WHERE 条件没走索引导致分批失效分批的前提是每次都能快速定位起始位置。如果 WHERE 中的过滤字段没索引或组合条件无法命中索引最左前缀MySQL 每次仍要全表扫描找 1000 行性能不升反降。 通义听悟 阿里云通义听悟是聚焦音视频内容的工作学习AI助手依托大模型帮助用户记录、整理和分析音视频内容体验用大模型做音视频笔记、整理会议记录。

更多文章