mysql中批量插入数据时的性能优化技巧

来源:这里教程网 时间:2026-02-28 20:43:32 作者:

用 INSERT ... VALUES 多值插入,别单条循环

单条

INSERT INTO table (a,b) VALUES (1,2)
执行 1000 次,和一条
INSERT INTO table (a,b) VALUES (1,2),(3,4),(5,6),...,(1999,2000)
执行 1 次,性能差距可达 10 倍以上。MySQL 要为每条语句做解析、权限检查、日志写入等开销,多值插入能大幅摊薄这些成本。

单次插入行数建议控制在 1000 行以内(受
max_allowed_packet
限制,可查
SHOW VARIABLES LIKE 'max_allowed_packet'
避免拼接超长 SQL 导致内存溢出或网络超时;可用分批提交,比如每 500 行一组 注意:如果某一批中某一行违反唯一约束,整批会失败;需根据业务容忍度决定是否拆更小批次或加
ON DUPLICATE KEY UPDATE

关闭自动提交 + 手动事务包裹

默认开启

autocommit=1
时,每条
INSERT
都是一次独立事务,强制刷盘(尤其是
innodb_flush_log_at_trx_commit=1
时),I/O 成为瓶颈。

显式执行
SET autocommit = 0
,再用
BEGIN
/
START TRANSACTION
包裹批量操作,最后
COMMIT
不推荐用
SET autocommit = 0
后不配
COMMIT
—— 连接断开会导致事务回滚,且长事务会拖慢 MVCC 清理和锁等待
若中途出错需回滚,用
ROLLBACK
;但注意大事务回滚本身也耗时,建议先校验数据再提交

临时禁用唯一/外键检查与索引更新

大批量导入前,若确认数据合规,可跳过约束校验和二级索引维护,显著提速。

禁用唯一性检查:
SET unique_checks = 0
(导入后记得
SET unique_checks = 1
,否则后续插入可能破坏唯一性)
禁用外键检查:
SET foreign_key_checks = 0
(同样需恢复)
注意:禁用后不会重建索引,仅跳过插入时的校验;索引仍存在,只是暂不更新。如需彻底跳过索引构建,得用
LOAD DATA INFILE
配合
DISABLE KEYS

优先用 LOAD DATA INFILE 替代 INSERT

当数据源是本地文件(如 CSV),

LOAD DATA INFILE
是 MySQL 官方最高效的批量导入方式,比等量
INSERT
快 20 倍以上,因它绕过 SQL 解析层,直接走存储引擎接口。

LOAD DATA INFILE '/tmp/data.csv'
INTO TABLE my_table
FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;
要求文件在数据库服务器本地(除非启用
local_infile=1
并用
LOAD DATA LOCAL INFILE
IGNORE 1 ROWS
跳过表头;字段顺序必须与表定义严格一致,或用列名映射(如
(col_a, col_b)
导入期间会自动禁用索引更新(
DISABLE KEYS
),结束后重建,比手动关/开更快更安全
真正卡住性能的往往不是 SQL 写法本身,而是事务粒度、约束校验时机和数据落盘策略。尤其要注意
unique_checks
foreign_key_checks
关了没恢复,或者
max_allowed_packet
不够导致批量语句被截断 —— 这类问题不会报错,只会静默失败几行数据。

相关推荐