批量插入比单条INSERT快得多,因其减少事务开销、日志刷盘、索引更新与网络往返;推荐每批1000–5000行,配合显式事务、禁用非必要索引/约束及合理调优innodb日志参数。

批量插入比单条 INSERT 快得多
单条 INSERT 每次都走完整事务流程,网络往返、日志刷盘、索引更新开销大。换成批量插入后,MySQL 只需一次解析、一次日志写入(取决于 innodb_flush_log_at_trx_commit)、更少的索引分裂。
- 用
INSERT INTO t VALUES (...), (...), (...)一次性插入多行,建议每批 1000–5000 行(太大易锁表或 OOM) - 避免在循环里拼接长 SQL,改用预处理 + 批量绑定(如 Python 的
executemany()、Java 的addBatch()) - 若数据来自文件,优先用
LOAD DATA INFILE—— 它绕过 SQL 解析层,速度通常快 5–20 倍
关闭自动提交 + 合理控制事务大小
默认 autocommit=1 会让每条写入都触发一次 redo log 刷盘(尤其当 innodb_flush_log_at_trx_commit=1),这是写入瓶颈常见根源。
- 显式用
BEGIN/START TRANSACTION开启事务,批量写完再COMMIT - 单个事务别太大(例如超 10 万行或持续超 10 秒),否则可能阻塞 MVCC 清理、拖慢其他查询,甚至触发
innodb_lock_wait_timeout - 确认业务能接受“事务内部分失败即全部回滚”,不能只靠
INSERT IGNORE或ON DUPLICATE KEY UPDATE掩盖逻辑缺陷
调整 InnoDB 日志与缓冲区参数
写入性能卡在磁盘 I/O 时,innodb_log_file_size 和 innodb_log_buffer_size 是关键调节点,但改错会丢数据或启动失败。
-
innodb_log_file_size建议设为 1–4 GB(总日志容量 = 文件数 × 单文件大小),太小导致频繁 checkpoint,太大延长崩溃恢复时间 -
innodb_log_buffer_size默认 16MB,写入含大字段(如 JSON、TEXT)时可提到 32–64MB,避免 buffer 不够而频繁刷到 log file - 生产环境慎调
innodb_flush_log_at_trx_commit:设为2(每秒刷日志)可大幅提升吞吐,但异常断电会丢最多 1 秒数据;0更危险,不推荐
写入前清理非必要索引与约束
每新增一行,MySQL 都要维护所有二级索引、检查外键、触发器、唯一约束——这些全在写入路径上,且无法并行。
- 导入临时表或 ETL 场景下,可先
DROP INDEX,写完再CREATE INDEX(比边写边建快一个数量级) - 确认
FOREIGN KEY是否真被应用层依赖,否则关掉(SET FOREIGN_KEY_CHECKS=0)能省大量校验开销 - 避免在写入密集表上设过多触发器,尤其是调用存储过程或跨库操作的触发器
innodb_log_file_size 和事务批量大小这两个参数最常被低估,改之前务必在测试库验证崩溃恢复行为和磁盘空间占用。











