mysql如何避免大批量数据修改锁全表_使用分批提交技术

MySQL UPDATE大表时看似锁全表,实为行锁升级+MVCC版本链拉长导致阻塞;分批更新须基于主键范围切分、控单事务≤1000行、加短延时,禁用OFFSET;无索引时优先加索引或改用主键子查询。UPDATE 大表时为什么锁全表MySQL 的 UPDATE 在未命中索引或扫描行数过多时,InnoDB 会升级锁粒度------从行锁退化为间隙锁甚至表级意向锁,配合事务隔离级别(尤其是 REPEATABLE READ),实际效果就是"像锁了整张表"。你看到的"卡住其他查询",往往不是真锁表,而是大量行锁堆积 + MVCC 版本链拉长,导致后续语句等锁、等回滚、等 purge 线程清理旧版本。常见错误现象:SHOW PROCESSLIST 里一堆 Updating 状态;SELECT 查询明显变慢甚至超时;INFORMATION_SCHEMA.INNODB_TRX 显示事务长时间运行且 TRX_ROWS_LOCKED 高达百万级。分批 UPDATE 的核心控制点分批不是简单加个 LIMIT 就完事。关键在三件事:用主键/唯一索引驱动分页、控制每批事务大小、避免 OFFSET 滚动扫描。必须基于主键范围切分,例如:WHERE id BETWEEN ? AND ?,而不是 LIMIT 1000 OFFSET 10000(后者越往后越慢,且可能漏数据)每批提交前确认影响行数,用 ROW_COUNT() 判断是否还有数据可处理单事务控制在 1000 行以内(具体看单行大小和 binlog 格式,STATEMENT 模式下大事务更危险)批次间加短延时(如 SLEEP(0.1)),缓解主从复制压力和锁竞争示例逻辑(伪代码):SET @start_id = 0;WHILE @start_id < (SELECT MAX(id) FROM t) DO UPDATE t SET status = 1 WHERE id > @start_id AND id <= @start_id + 1000; SELECT ROW_COUNT() INTO @affected; IF @affected = 0 THEN LEAVE; END IF; SET @start_id = @start_id + 1000; COMMIT; DO SLEEP(0.1);END WHILE;WHERE 条件没走索引怎么办这是最常踩的坑:以为加了 LIMIT 就安全,结果执行计划显示 type: ALL,全表扫描+全表加锁。分批的前提是每次都能快速定位到下一批起点。 文心快码 文心快码(Comate)是百度推出的一款AI辅助编程工具

相关推荐
Wx-bishekaifayuan4 小时前
springboot桂味美食分享系统40540-计算机课程设计、毕业设计
spring boot·后端·python·django·课程设计·express·旅游
创邻科技4 小时前
国产图数据库刷新 LDBC 世界纪录:创邻科技 Galaxybase 在 SF100、SF300、SF1000 测试中全面领先”
数据库·科技
GreatSQL社区4 小时前
主从复制SQL线程中断——字符集砸出的坑
java·数据库·算法
Metaphor6924 小时前
如何快速拆分超大 Excel 文件【Python 教程】
python·excel
XLYcmy5 小时前
AI 赋能后中文与英文数据库对比分析报告 上
数据库·ai·llm·prompt·检索·wos·cnki
孟健5 小时前
从单体失控到解耦管道:用 Unix 哲学重构 Anthropic 式多 Agent 动态工作流
人工智能·python·架构
小白快快跑哦5 小时前
python-字符串全解(六):正则表达式-前后相断言
开发语言·python·正则表达式·前后相断言
kimnoic5 小时前
Python数据分析中正则表达式匹配字符串与常用函数示例详解
开发语言·python
许墨の小蝴蝶5 小时前
Pillow 替换图片文字后字号偏小的排查
python·pillow
这个DBA有点耶5 小时前
ELT 工具选型完整指南:从 ETL 差异分析到工程落地
数据库·架构·代码规范