如何提升MySQL批量插入INSERT的速度_通过开启事务与多值合并

梦浩君_7439

梦浩君_7439

2026-05-08

185人浏览

原创

不开事务+单条INSERT最慢;改用事务包裹+多值合并插入可提速10–50倍,因减少SQL解析、磁盘IO、锁开销及日志刷盘次数。

如何提升mysql批量插入insert的速度_通过开启事务与多值合并

直接结论:不开事务 + 单条INSERT,是批量插入最慢的写法;只要把这两点改掉,90% 的场景下插入速度能提升 10–50 倍。

为什么单条 INSERT + 自动提交这么慢

MySQL 默认 autocommit=1,每执行一条 INSERT 就自动开启并提交一个事务。这意味着:每次都要写 redo log、刷盘、更新索引 B+ 树、加锁释放锁。哪怕只插 100 行,也是 100 次磁盘 IO 和 100 次 SQL 解析开销。

常见错误现象:SHOW PROCESSLIST 看到大量 query end 或 commit 状态卡住;监控显示 Innodb_log_waits > 0;插入耗时随数据量线性增长,毫无并发收益。

实操建议:

  • 确认当前行为:SELECT @@autocommit; —— 生产环境默认是 1
  • 不要依赖框架默认连接配置(如 Spring 的 @Transactional 只包业务逻辑,不包纯数据导入)
  • 在导入脚本开头显式关闭:SET autocommit = 0;,结尾再 COMMIT;

怎么合并多条 INSERT 成一条语句

把 1000 条单独的 INSERT INTO t(a,b) VALUES (1,2); 改成一条含 1000 组值的语句,核心是减少网络往返和 SQL 解析次数。

示例对比:

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
-- 慢(1000 次解析 + 1000 次网络包)
INSERT INTO user (id, name) VALUES (1, 'a');
INSERT INTO user (id, name) VALUES (2, 'b');
...
-- 快(1 次解析 + 1 次大包)
INSERT INTO user (id, name) VALUES (1, 'a'), (2, 'b'), ..., (1000, 'z');

注意事项:

  • max_allowed_packet 限制单条语句大小,默认 4MB,插 10 万行可能超限,需提前调大(如设为 64M)
  • 值太多会增加客户端内存压力,建议单条控制在 1000–5000 行之间(视字段长度而定)
  • 主键冲突时整条语句失败,不如分批可控;可用 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE 缓冲

事务粒度与批量大小怎么权衡

事务不是越大越好。太长的事务会占用大量 undo log、锁住更多记录、拖慢其他查询,甚至触发 innodb_lock_wait_timeout。

推荐做法:

  • 每 1000–10000 行做一次 COMMIT,具体看单行大小和服务器内存
  • 避免跨表大事务:不同表的插入尽量拆开事务,减少锁竞争
  • 如果用 LOAD DATA LOCAL INFILE,它本身就是一个原子操作,无需额外套事务
  • 注意 binlog 格式:ROW 模式下大事务生成巨量 binlog,可能压垮从库

容易被忽略的底层影响点

即使代码层做了事务 + 多值合并,性能仍上不去?大概率卡在这些地方:

  • innodb_flush_log_at_trx_commit = 1(默认)→ 插入时强制刷盘 redo log;临时导入可设为 0,但断电会丢最多 1 秒数据
  • 目标表有太多二级索引 → 每插一行,所有索引都要更新;导入前可 DROP INDEX,导完再重建
  • 主键无序插入(如用 UUID 或随机数)→ 频繁页分裂,B+ 树重平衡;尽量按主键递增顺序提供数据
  • 没关 foreign_key_checks 和 unique_checks → 每行都校验外键和唯一约束,导入前可临时禁用

真正快的批量插入,从来不是只改 SQL 写法,而是代码层、配置层、表结构层同步动刀——其中最容易被跳过的,是禁用约束检查和调整日志刷盘策略。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4583

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

951

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1189

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6541

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3303

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6500

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8941

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1210

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1072

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 192人学习