单条INSERT在高并发下卡住是因为每条都默认独立事务,触发完整WAL流程:解析SQL、加锁、写redo log、刷binlog、提交刷盘;10万次重复操作导致IO、锁竞争和CPU解析全面瓶颈,必须用显式事务批量提交。

单条INSERT在高并发下为什么卡住
因为每条INSERT都默认开启独立事务,触发完整 WAL 流程:解析 SQL、加行锁、写 redo log、刷 binlog、提交并刷盘。100 个并发线程各插 1000 行,等于执行 10 万次事务提交——锁竞争、日志刷盘、CPU 解析全拉满,IO 瓶颈立刻暴露。
必须用显式事务包裹批量INSERT
不手动开事务,哪怕用了INSERT INTO t VALUES (),(),(),每批仍被当做一个自动提交事务,性能提升有限。正确做法是客户端控制事务边界:
-
BEGIN后再拼接多批(如每批 500 行),而非每批自己BEGIN; ... ; COMMIT - 单个事务内总行数建议 ≤ 10 万,避免
undo log膨胀拖慢回滚或占用过多 buffer pool - Java/JDBC 场景下,别只依赖
addBatch(),必须配connection.setAutoCommit(false)+ 最后commit()
max_allowed_packet 和 innodb_buffer_pool_size 是隐形瓶颈
大批量 INSERT 的 SQL 文本长度和中间缓存都受这两个参数压制:
解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。
-
max_allowed_packet控制单条语句最大长度,默认 4MB;插入 2000 行含中文的记录很容易超限,报错ERROR 1153 (08S01): Got a packet bigger than 'max_allowed_packet' bytes -
innodb_buffer_pool_size太小(比如仅 128MB)时,批量写入会频繁触发脏页刷盘,实测写入速度可能下降 3–5 倍 - 建议值:
max_allowed_packet=64M,innodb_buffer_pool_size设为物理内存的 50%–75%(SSD 环境下更敏感)
LOAD DATA INFILE 比 INSERT 快但限制多
它绕过 SQL 层,直写引擎,百万级导入常压到 10–20 秒。但三个硬约束常被忽略:
- 文件必须放在 MySQL 服务端本地,或客户端连接时加
--local-infile=1且服务端SET GLOBAL local_infile = ON -
secure_file_priv非空时,文件只能放在此目录下,否则报ERROR 1148 (42000) - 遇到唯一键冲突默认整批失败,得加
IGNORE或改用REPLACE,但后者会触发 DELETE+INSERT,索引重建开销大
真正高并发写入场景里,LOAD DATA 很难直接用于在线业务流,它更适合离线 ETL;而混合使用「分批事务 + 合理 packet + buffer pool 调优」才是线上批量插入的稳定解法。


















