load data infile 比 insert 快的本质是绕过 sql 解析与逐行事务开销,直接由 server 层批量处理文件流;其高效依赖文件位于 secure_file_priv 目录、严格匹配分隔符与换行符、禁用触发器/外键,并需 utf8mb4 编码及 \n 表示 null。

Load Data Infile 为什么比 INSERT 快得多
本质是绕过 SQL 解析与逐行事务开销,直接由 MySQL Server 层将文件内容按行切分、转换类型、写入存储引擎。INSERT 每条语句都要走解析 → 优化 → 执行 → 日志刷盘全流程,而 LOAD DATA INFILE 把整块数据当“原始流”处理,批量提交更少、锁粒度更粗、IO 更连续。
常见错误现象:ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option —— 表示 MySQL 只允许从特定目录读文件,不是路径权限问题,而是配置强制限制。
- 必须确保数据文件在
secure_file_priv返回的路径下(查法:SHOW VARIABLES LIKE 'secure_file_priv';) - 字段分隔符、行结束符要和实际文件严格一致,比如 Windows 换行用
\r\n,Linux 是\n,错一个字符就卡在某行不动 - 目标表不能有触发器或外键约束(会自动禁用),否则报错;如有需要,先
SET FOREIGN_KEY_CHECKS = 0;和SET SQL_LOG_BIN = 0;(仅限从库不需同步时)
INSERT 多值语法怎么写才不拖慢速度
单条 INSERT INTO t VALUES (...), (...), (...); 是唯一能接近 LOAD DATA INFILE 效率的纯 SQL 方式。但很多人误以为“拼多条 INSERT 语句”也行,其实每条独立 INSERT 都是一次 round-trip + 一次事务开销,1000 行拆成 1000 条,比 1 条含 1000 组值的慢 5–10 倍以上。
使用场景:无法用 LOAD DATA INFILE(如文件在客户端本地、无服务端文件访问权限)、或需动态生成部分字段值(如加时间戳、UUID)。
- 每批控制在 1000–5000 行之间:太小(10000)易触发
max_allowed_packet错误(查法:SHOW VARIABLES LIKE 'max_allowed_packet';) - 显式开启事务包裹多批:
BEGIN; INSERT ...; INSERT ...; COMMIT;,否则每批仍默认自动提交 - 避免在循环里反复
INSERT单行,也别用 ORM 的 save() 逐条写——那是为交互设计的,不是为吞吐量
字符集和 NULL 处理的坑在哪
LOAD DATA INFILE 对编码和空值极其敏感,出错常不报具体哪一行,只停在第一个失败点。INSERT 多值虽稍好,但字段类型隐式转换失败时也会静默截断或转成 0/''。
典型错误现象:Incorrect integer value: '' for column 'id' at row 1,或中文变问号、时间字段全成 0000-00-00。
- 数据文件必须用 UTF8MB4 编码保存(不是 UTF-8 BOM,也不是系统默认 ANSI),并在
LOAD DATA语句中显式声明:CHARACTER SET utf8mb4 - NULL 字段不能留空格或空字符串,得用
\N(反斜杠 N)表示,例如:123,\N,"hello"→ 第二列插入 NULL;若用空字符串"",会转成空串或 0,取决于字段类型 - 日期字段建议用
'2024-01-01'格式,避免1/1/2024这类模糊格式,MySQL 默认只认Y-m-d或Y-m-d H:i:s
什么时候该放弃 Load Data Infile 改用其他方式
不是所有“大量数据”都适合 LOAD DATA INFILE。它快,但依赖文件落盘、权限、格式规整,一旦中间环节不可控,调试成本远高于写几行 Python 或 Go 脚本做流式批量 INSERT。
适用边界很明确:
- 数据源是干净 CSV/TXT,且能传到 MySQL 服务器本地磁盘(或容器内可挂载路径)
- 字段顺序、类型、空值规则完全固定,无需运行时判断或补字段
- 不需要对每行做校验、去重、映射(比如把 A 列的 "yes"/"no" 映射成 1/0)
- 你有
FILE权限,且 DBA 不反对临时关闭sql_log_bin或外键检查
如果其中任意一条不满足,老实用带事务控制的批量 INSERT,或者导出成 Parquet + ClickHouse 做预处理——硬推 LOAD DATA 只会让问题从“慢”变成“错得悄无声息”。











