批量插入比单条快5–8倍,因减少解析、加锁、日志刷盘和网络往返;建议每批100–500行,显式事务包裹,并调优buffer pool与redo log参数。

批量插入比单条 insert 快多少?
单条 INSERT INTO t VALUES (...) 每次都要走完整事务流程:加锁、写 redo、刷 binlog、提交。而批量插入如 INSERT INTO t VALUES (...), (...), (...) 只需一次解析、一次加锁(行锁粒度不变但锁竞争窗口缩短)、一次事务提交,网络往返和日志刷盘次数大幅下降。实测在千级 QPS 场景下,100 行一批比单行快 5–8 倍;超过 500 行后收益趋缓,且可能触发 max_allowed_packet 限制。
实操建议:
- 控制每批
INSERT行数在 100–500 之间,用程序分批组装 SQL,避免拼接过长字符串导致内存或超包错误 - 显式开启事务包裹多批:用
BEGIN; ... INSERT ... ; INSERT ... ; COMMIT;,否则每批仍独立提交 - 禁用自动提交:
SET autocommit = 0;,但注意连接生命周期内必须显式COMMIT或ROLLBACK,否则会锁表或阻塞后续操作
LOAD DATA INFILE 真的比 INSERT 快?
是的,LOAD DATA INFILE 是 MySQL 内部 C 实现的高速导入路径,绕过 SQL 解析层,直接构造记录并批量刷入 buffer pool 和磁盘。在 SSD 上导入百万级 CSV,通常比等效批量 INSERT 快 3–10 倍。但它有硬性前提:文件必须在 MySQL 服务端本地(或启用了 local_infile=ON 并信任客户端),且格式严格(字段分隔符、换行、转义需匹配)。
常见卡点:
-
ERROR 1148 (42000): The used command is not allowed with this MySQL version→ 检查secure_file_priv变量值,文件必须放在此目录下;或客户端连接时加--local-infile=1并服务端开启local_infile - 中文乱码 → 在语句末尾加
CHARACTER SET utf8mb4,且确保源文件编码一致 - 唯一键冲突导致整批失败 → 加
IGNORE跳过重复行,或用REPLACE替换,但后者会触发 DELETE+INSERT,影响性能
innodb_buffer_pool_size 设太小会拖慢并发写入?
会,而且非常明显。InnoDB 所有写操作先写入 buffer pool,再异步刷盘。如果 innodb_buffer_pool_size 远小于热数据+待写数据总量,就会频繁触发 LRU flush 和 checkpoint,造成大量随机 I/O,写入吞吐骤降,甚至出现 Waiting for query cache lock 类似假死现象。
调优原则:
- 专用数据库服务器:设为物理内存的 70%–80%,但不超过
innodb_buffer_pool_instances * 1G(避免实例间争用) - 写密集场景可适当降低
innodb_log_file_size(如从 48M 提到 256M),延长 checkpoint 周期,减少刷脏页压力 - 监控关键指标:
Innodb_buffer_pool_wait_free> 0 表示 buffer pool 不足;Innodb_log_waits> 0 表示 redo log 太小,正在阻塞写入
并发插入时主键用自增 ID 还是 UUID?
高并发写入下,优先选 BIGINT UNSIGNED AUTO_INCREMENT。UUID(尤其 UUID() 函数生成的)会导致严重页分裂:新值不单调,插入位置随机,buffer pool 中的索引页反复分裂、合并、重组织,CPU 和 I/O 开销陡增。实测在 16 核机器上,相同写入压力下 UUID 主键的 INSERT 吞吐比自增 ID 低 40% 以上,且 innodb_data_written 高出 2–3 倍。
如果业务强依赖分布式唯一 ID:
- 用
ULID或KSUID替代 UUID,它们时间有序,局部聚集性好 - 或采用「号段模式」:应用层预取一批自增 ID(如 1000–1999),本地分配,减少对 MySQL
auto_increment的争抢 - 绝对避免在写热点表上用
UUID()作为主键或二级索引前缀
实际压测中,最常被忽略的是 innodb_flush_log_at_trx_commit 和 sync_binlog 的组合效应。设为 1 最安全但最慢;设为 0 或 2 能显著提速,但主机崩溃可能丢最多 1 秒事务。这个权衡点不在 SQL 层,而在你的容灾设计里。











