首页/数据/SQL 速查/批量写入调优要点
性能与执行计划72 条

批量写入调优要点

多行 INSERT、批提交事务、批量接口开启驱动改写:把行级往返与提交压缩成批级。

SQL 速查数据更新于 2026-10-13

批量写入怎么提速

写入吞吐低通常不是磁盘慢,而是把本可以合并的动作拆成了很多次:一行一次插入、一行一次提交、一行一次网络往返。做法很直接——把多行合成一条语句,把多条语句合成一次网络往返,把多次提交合成一个事务,把每批的行数控制在合理区间。批量大小不是越大越好:事务太大会延长锁持有时间、放大失败重试的代价。

基本信息

适用平台MySQL 8.0 / PostgreSQL 12 及以上,应用侧与驱动侧配合
语句级合并一条插入语句写多组值,一次解析
事务级合并按批提交,减少提交开销与刷盘次数
驱动改写连接参数开启后把多条插入合并发送
批量大小常见区间为几百到几千行,按单批耗时调整

典型使用场景

  • 日志与埋点入库:高频小批量写入,需要合并往返
  • 数据迁移:从外部文件批量导入,需权衡批大小与事务长度
  • 接口批量落库:一次请求带多条记录,用多值插入
  • 定时任务写入:按批提交并记录进度,便于中断续跑
  • 排查写入瓶颈:区分是网络往返、提交开销还是索引维护导致的慢

合并写入示例

合并写入示例
-- 单语句多行插入:一次解析、一次网络往返
INSERT INTO events (uid, kind, created_at) VALUES
  (1, 'click', NOW()),
  (1, 'view',  NOW()),
  (1, 'order', NOW());

-- 大批量按批提交(结构示意)
-- START TRANSACTION;
--   每 1000 行执行一次插入
-- COMMIT;                  ← 提交后开始下一批

-- 驱动层合并:开启连接参数后,批处理语句会被合并发送
-- MySQL 连接参数:rewriteBatchedStatements=true
-- PostgreSQL 连接参数:reWriteBatchedInserts=true

-- 导入超大文件时优先用数据库自带的批量导入通道
-- MySQL:LOAD DATA INFILE
-- PostgreSQL:COPY

优化点与代价

优化点收益代价
语句级合并解析与往返次数下降单条语句过长时解析内存上升
事务级合并提交与刷盘次数下降事务变长,锁持有时间增加
驱动改写自动合并批处理语句需确认驱动版本与参数行为
专用导入通道大文件导入速度最高数据格式要求严格,需预处理
关闭不必要的索引写入期间维护成本下降导入后需重建索引,期间查询变慢
批太大与批太小各有代价:太大时单批失败要整体重做,长事务还会推高复制的延迟;太小时往返开销占比高。用单批耗时作为调整依据,先测后调。
导入期间临时去掉次要索引、导入后重建,常比边写边维护索引快得多。重建索引本身也占资源,安排在业务低峰执行。

易错点

  • 逐行自动提交:每条一次事务开销,吞吐被往返与刷盘拖住,磁盘再快也救不回来
  • 批过大造成长事务:锁与回滚段压力上升,失败重试代价也大
  • 开启驱动改写参数后不做验证:参数行为与预期不符时批量语句实际仍逐条发送
  • 导入时保留全部索引:写入过程中索引维护开销成倍增加,导入时间远超预期
  • 批量失败后整批重做而不做去重:唯一键冲突导致重试永远失败

数据来源与参考

  • MySQL 8.0 Reference Manual · INSERT
  • PostgreSQL Documentation · INSERT
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌