LOAD DATA INFILE比批量INSERT快数十倍,根本原因是其绕过SQL解析、权限校验和网络往返,直接由Server层将文件作为原始数据流切分并批量写入存储引擎;实测10万行CSV导入仅需0.7秒,而等效多值INSERT耗时近90秒,差距达120倍。

LOAD DATA INFILE 确实比批量 INSERT 快数十倍,但前提是绕过 SQL 解析层、禁用事务开销、直写存储引擎——不是简单换条命令就能生效。
为什么 LOAD DATA INFILE 能甩开 INSERT 几条街
根本原因不是“语法高级”,而是执行路径完全不同:INSERT 每批都要走完整 SQL 生命周期(解析 → 优化 → 权限校验 → 执行 → binlog刷盘),而 LOAD DATA INFILE 把文件当原始数据流处理,Server 层直接切行、转类型、喂给 InnoDB 的 bulk insert 接口,跳过所有 SQL 层开销。
实测对比(10 万行 CSV):LOAD DATA INFILE 耗时约 0.7 秒;等效的多值 INSERT(单语句含 1000 行 × 100 批)耗时近 90 秒——差了 120 倍,不是“快一点”,是架构级差异。
- 网络往返:INSERT 多批需多次 TCP 往返;LOAD DATA 服务端模式只传一次命令,文件在本地读取
- 锁粒度:INSERT 每批默认自动提交,频繁加锁/释放;LOAD DATA 整个导入过程可控制为单事务(加
LOCAL或显式BEGIN/COMMIT) - IO 模式:LOAD DATA 使用连续大块读 + 预分配页,比 INSERT 的随机小写更适配磁盘顺序吞吐
LOAD DATA INFILE 必须调的几个参数
不设对参数,LOAD DATA INFILE 很可能卡住、报错或降速到和 INSERT 差不多。关键参数不是可选,是必填:
-
FIELDS TERMINATED BY ',':必须和 CSV 实际分隔符严格一致,逗号、制表符、竖线不能猜,Windows 的\r\n和 Linux 的\n也得匹配 -
LINES TERMINATED BY '\n':错写成'\r\n'在 Linux 服务器上会整行吞掉或卡死 -
CHARACTER SET utf8mb4:不显式指定,中文字段全变问号,且错误不提示具体哪一行 -
SET子句处理动态字段:比如时间戳用@created_at变量 +STR_TO_DATE()转换,避免字段类型不匹配静默截断 - 跳过首行:加
IGNORE 1 ROWS,否则表头被当数据插进去
常见报错和对应解法
这些错误不报行号、不指明字段,只停在第一个失败点,排查要靠“缩小范围+验证参数”:
-
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option:不是权限问题,是 MySQL 强制只允许从secure_file_priv目录读文件。查路径:SHOW VARIABLES LIKE 'secure_file_priv';,把 CSV 放进去再试 -
ERROR 1148: The used command is not allowed with this MySQL version:客户端模式未开启,需先执行SET GLOBAL local_infile = 1;,连接时加--local-infile参数 -
ERROR 29: File '/path/data.csv' not found:服务端模式下路径不在secure_file_priv内,或 MySQL 进程用户(如mysql)对该文件不可读 - 导入后某列全是
0或空字符串:字段类型与 CSV 值不兼容(如字符串塞进 INT),没报错但静默转换,加SET显式转换或预处理清洗
什么时候该放弃 LOAD DATA,退回去用批量 INSERT
LOAD DATA 不是万能钥匙,遇到以下情况硬上反而更慢、更难维护:
- CSV 文件在你本地,MySQL 服务端无法访问(比如云数据库 RDS 默认禁用
LOCAL INFILE,且不开放secure_file_priv目录写入) - 需要在插入时动态生成字段值(如 UUID、当前时间、关联另一张表查出的 ID),
LOAD DATA不支持子查询,只能靠SET变量 + 函数,能力有限 - 数据质量极差,脏数据比例高,又要求“错多少行就跳多少行”,
LOAD DATA的IGNORE或REPLACE是整行跳过,没法做字段级容错 - 单次导入量小于 5 万行,且后续还要频繁增删改——这时用带事务包裹的多值
INSERT(每批 1000–2000 行)开发成本更低,调试更直观
真正卡点在于:LOAD DATA 的快,建立在“数据干净、路径可控、格式确定”的前提上。一旦这三个条件崩一个,它就从加速器变成阻塞器。别迷信命令本身,盯住你的数据链路是否闭环。


















