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助手,依托大模型,帮助用户记录、整理和分析音视频内容,体验用大模型做音视频笔记、整理会议记录。

更多推荐