load data infile比insert快几十倍,因其绕过sql解析、权限校验、单条事务提交和网络往返,由服务端直接解析文件并批量写入存储引擎;而insert即使批量仍需完整执行流程,autocommit=1时日志刷盘百万次。

LOAD DATA INFILE 为什么比 INSERT 快几十倍
因为它根本没走 SQL 解析、权限校验、单条事务提交和网络往返——MySQL 服务端直接把文件按行切分,字段解析后构造内存行对象,批量刷进 InnoDB/BTree 结构。而百万条 INSERT 即使写成 INSERT INTO t VALUES (...), (...), (...),每批仍要过完整执行器流程,autocommit=1 下等于刷盘百万次日志。
执行前必须确认的 4 个硬性条件
跳过任一,LOAD DATA INFILE 会报错退出或静默失败:
-
secure_file_priv值不能为NULL;若为具体路径(如/var/lib/mysql-files/),你的 CSV 文件必须放在此目录下,不能写~/data.csv或./data.csv - 当前 MySQL 用户需有
FILE权限:GRANT FILE ON *.* TO 'your_user'@'%'; - 字段顺序、类型、空值约束必须与表结构严格对齐;不匹配会导致
ERROR 1366 (HY000)或字段截断 - 若用
LOAD DATA LOCAL INFILE,服务端需SET GLOBAL local_infile = ON(需SUPER权限),且客户端连接时显式传local_infile=True(Python)或加--local-infile=1(命令行)
字段分隔、换行与特殊字符怎么配才不丢数据
常见错误不是语法错,而是字段错位或末尾多出 \r:
- Windows 生成的 CSV 默认用
\r\n换行,LINES TERMINATED BY '\n'会导致最后一列带\r;应改用LINES TERMINATED BY '\r\n' - 地址字段含逗号(如
"北京市,朝阳区")必须配合FIELDS ENCLOSED BY '"',否则会被误切为两列 - 时间字段为
"2024-03-15 14:22:08"时不能直插,得用SET created_at = STR_TO_DATE(@created_at, '%Y-%m-%d %H:%i:%s') - 跳过 CSV 表头:加
IGNORE 1 LINES;跳过某列:在列列表中用@dummy占位
导入中途失败了,怎么定位和续传
LOAD DATA INFILE 不支持断点续传,且默认遇到第一处格式错误就停,不提示行号。真正能用的补救方式只有三种:
- 先用小样本测试:取前 1000 行另存为
test.csv,跑通再换全量 - 加
IGNORE跳过冲突行(如主键重复),但注意它也会跳过其他错误,导入后务必查SHOW WARNINGS - 更稳妥的做法是走临时表:先
CREATE TABLE t_temp LIKE t,导入到t_temp,清洗验证后再INSERT INTO t SELECT ... FROM t_temp
最容易被忽略的是:错误不会告诉你哪一行坏了,只会报“Incorrect integer value”或“Data too long”,你得靠 SHOW WARNINGS LIMIT 10 看上下文,再结合原始文件用 sed -n '1234,1236p' data.csv 定位具体行。











