批量插入性能优化需四步:一、显式开启事务并统一提交;二、分批次提交避免长事务;三、连接初始化时关闭autocommit;四、临时禁用外键和唯一性检查。

如果您在执行数据库批量插入时发现耗时过长、CPU或I/O占用异常升高,则很可能是由于每条INSERT语句都在独立事务中执行,导致频繁日志刷盘与锁竞争。以下是提升性能的具体操作方法:
一、显式开启事务并包裹整个Insert循环
默认autocommit=1时,每个INSERT都会触发完整事务生命周期(begin→write log→flush→commit),极大增加磁盘I/O开销。通过手动控制事务边界,可将N次提交压缩为1次,显著降低redo log和binlog写入频率。
1、在执行批量插入前,执行START TRANSACTION或BEGIN语句显式开启事务。
2、将原本独立执行的多条INSERT语句全部置于该事务范围内,不进行中间COMMIT。
3、所有INSERT语句执行完毕后,统一执行COMMIT完成持久化。
4、若任意一条INSERT失败,立即执行ROLLBACK回滚全部变更,确保数据一致性。
二、分批次提交避免长事务风险
单一大事务插入数十万行会导致undo log膨胀、锁持有时间过长、主从延迟加剧,甚至触发MySQL的innodb_lock_wait_timeout中断。按固定行数切分并逐批提交,可在性能与稳定性间取得平衡。
1、设定每批次插入行数,推荐值为5000行(可根据max_allowed_packet与内存压力动态调整)。
2、使用array_chunk()(PHP)、itertools.batched()(Python 3.12+)或手动索引偏移对原始数据集进行等长切片。
3、对每个子集单独开启事务、执行批量INSERT、调用COMMIT,形成“小事务流水线”。
4、在每批次提交后检查返回影响行数,若为0或报错则终止后续批次并触发整体回滚逻辑。
三、关闭自动提交并配合事务控制
仅依赖BEGIN/COMMIT不足以规避驱动层隐式提交行为。某些数据库连接库(如PDO、JDBC)在执行DML语句时会自动检测autocommit状态并强制干预。必须在连接初始化阶段彻底关闭自动提交机制。
1、在获取数据库连接后,立即执行SET autocommit = 0语句禁用自动提交。
2、确认当前会话的autocommit变量值为OFF,可通过SELECT @@autocommit验证。
3、此后所有INSERT均不会自动提交,必须显式调用COMMIT或ROLLBACK。
4、事务结束后,如需恢复自动提交模式,执行SET autocommit = 1,但建议保持关闭直至批量任务完全结束。
四、禁用外键与唯一性检查以加速写入
在已知源数据符合约束条件的前提下,临时跳过外键校验与唯一索引维护,可绕过大量实时计算与B+树节点分裂操作,使插入吞吐量提升3–8倍。该操作仅适用于离线导入或灰度发布窗口期。
1、执行SET FOREIGN_KEY_CHECKS = 0关闭外键约束检查。
2、执行SET UNIQUE_CHECKS = 0禁用唯一索引重复性校验。
3、执行批量INSERT语句(仍需处于同一事务内)。
4、插入完成后,立即执行SET FOREIGN_KEY_CHECKS = 1与SET UNIQUE_CHECKS = 1恢复校验机制。










