load data infile比insert快数十倍,因其绕过sql解析、权限校验、网络往返及逐条事务日志刷盘,直接由服务端批量解析文件并写入存储引擎;而insert即使批量仍需完整sql生命周期,受限于max_allowed_packet等参数。

LOAD DATA INFILE 为什么比 INSERT 快这么多?
因为 LOAD DATA INFILE 是 MySQL 原生批量导入机制,绕过了 SQL 解析、单条事务开销和网络往返——它直接将文本按行切分、解析字段、构造内存行对象,再批量刷入存储引擎。而百万条 INSERT 语句默认每条都是独立事务(尤其在 autocommit=1 时),光日志刷盘和锁竞争就拖垮性能。
但前提是:文件必须位于 MySQL 服务端本地(或启用了 LOCAL 模式且客户端/服务端都允许),且格式严格对齐表结构。
实际执行前必须检查的 4 个硬性条件
跳过任一检查,LOAD DATA INFILE 会静默失败或报错如 ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option...:
-
secure_file_priv系统变量值不能为NULL;若为具体路径(如/var/lib/mysql-files/),数据文件必须放在此目录下 - MySQL 用户需有
FILE权限:GRANT FILE ON *.* TO 'your_user'@'%'; - 目标表字段顺序、类型、空值约束需与文件字段一一匹配;不匹配会导致截断、隐式转换或报错
ERROR 1366 (HY000) - 若使用
LOCAL关键字(即从客户端读文件),需确保启动 mysqld 时未加--local-infile=0,且客户端连接时启用--local-infile=1
提升入库速度的关键参数组合
默认配置下仍可能卡在缓冲区或索引更新上。以下参数应在 LOAD DATA 执行前临时调整(执行完可恢复):
- 关闭唯一键和外键检查:
SET unique_checks=0, foreign_key_checks=0;—— 避免逐行校验开销 - 增大排序缓冲区:
SET sort_buffer_size = 256M;(根据服务器内存合理设,别超物理内存 25%) - 禁用自动提交:
SET autocommit = 0;,并在语句后显式COMMIT; - 若表有大量二级索引,考虑先
DROP INDEX,导入完成再重建(比边插边维护索引快 3–5 倍)
示例完整流程:
SET unique_checks=0, foreign_key_checks=0, autocommit=0; LOAD DATA INFILE '/var/lib/mysql-files/data.csv' INTO TABLE orders FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS; COMMIT; SET unique_checks=1, foreign_key_checks=1;
字段解析常见坑与绕过方式
遇到 ERROR 1261 (01000): Row 1 doesn’t contain data for all columns 或时间字段全变成 0000-00-00,大概率是字段分隔符/换行符不干净或类型不兼容:
- 确认 CSV 中没有未转义的换行符(尤其文本字段含 \n);建议用
LINES TERMINATED BY '\r\n'或统一用 Unix 换行 - 日期字段若为
"2024-03-15 14:22:08",目标列为DATETIME可直入;但若列为TIMESTAMP且含时区,需加SET col_name = STR_TO_DATE(@col_name, '%Y-%m-%d %H:%i:%s')显式转换 - 空字符串
""导入NOT NULL字段会失败;可在LOAD语句中用SET col_name = NULLIF(@col_name, '')转成 NULL - 千万避免用 Excel 直接另存为 CSV —— 它会悄悄把数字当科学计数法、删前导零、乱码;推荐用
sed/awk或 Pythonpandas.to_csv(index=False, quoting=csv.QUOTE_NONNUMERIC)
真正压测到百万级时,瓶颈往往不在 SQL 本身,而在磁盘 I/O 调度、InnoDB 的 innodb_buffer_pool_size 是否足够缓存索引页、以及日志文件(ib_logfile*)是否太小导致频繁 checkpoint。这些得看 SHOW ENGINE INNODB STATUS 里的 log sequence number 和 pending writes 指标。











