LOAD DATA INFILE 或 LOCAL INFILE 比逐条 INSERT 快 5–20 倍,但需解决路径权限、格式容错、换行与字符处理三大问题;前者读服务器磁盘文件,后者由客户端上传,适用云数据库等无SSH场景。

直接说结论:用 LOAD DATA INFILE 或 LOAD DATA LOCAL INFILE,比逐条 INSERT 快 5–20 倍,但必须绕开三个关键拦路虎——路径权限、格式容错、字符与换行处理。
LOAD DATA INFILE 和 LOAD DATA LOCAL INFILE 到底该选哪个
区别不在“快不快”,而在“文件在哪”和“谁有读权限”:
-
LOAD DATA INFILE:MySQL 服务端进程直接读取服务器磁盘上的文件(比如/var/lib/mysql-files/data.csv),要求你有服务器登录权限,且 MySQL 进程对那个路径有读取权 -
LOAD DATA LOCAL INFILE:客户端(你的本机)把文件发给服务端,适合你本地有 CSV、但没服务器 SSH 权限的场景(比如云数据库);但默认禁用,需两端同时开启 - 常见错误:
The used command is not allowed with this MySQL version—— 就是local_infile在服务端或客户端任一端没开 - 开法分两步:服务端执行
SET GLOBAL local_infile = ON(需 SUPER 权限);客户端连接时加参数,比如 Python 的pymysql.connect(..., local_infile=True),或命令行加--local-infile=1
导入失败总卡在“secure_file_priv”或“文件找不到”
不是路径写错了,而是 MySQL 主动拦住了你:
使用 qbo-mileage CLI 及用户凭证,从 Airtable、Outlook 或 Google Calendar 记录生成 QuickBooks Online 里程 CSV 文件。
- 报错
The MySQL server is running with the --secure-file-priv option so it cannot execute this statement:说明 MySQL 启动时加了--secure-file-priv,只允许从指定目录读文件 - 查当前允许路径:
SHOW VARIABLES LIKE 'secure_file_priv';,返回值如果是/var/lib/mysql-files/,你就得把 CSV 放进去,不能放桌面或/tmp - 想临时放开?改配置文件
my.cnf或my.ini的[mysqld]段,加一行secure_file_priv = "",然后重启 MySQL(生产环境慎用) - Windows 用户注意:
LINES TERMINATED BY '\n'在记事本保存的 CSV 里会失效,得写成'\r\n',否则最后一列可能多出\r
CSV 字段乱套、中文变问号、时间插不进去
不是编码玄学,是字段解析规则没对齐:
- 中文乱码:建表时用
utf8mb4,导入语句末尾显式加CHARACTER SET utf8mb4,例如LOAD DATA LOCAL INFILE 'data.csv' INTO TABLE t ... CHARACTER SET utf8mb4 - 字段含逗号或换行符(如地址字段
"北京市,朝阳区\n建国路1号"):必须配FIELDS ENCLOSED BY '"' LINES TERMINATED BY '\n',否则 MySQL 在第一个逗号就切错了 - CSV 有标题行?加
IGNORE 1 LINES;但注意它跳的是物理第一行,不是逻辑首数据行 - 时间字段是
"2024-03-15 14:22:08"?不能直插,要用SET created_at = STR_TO_DATE(@created_at, '%Y-%m-%d %H:%i:%s')转换;先声明变量接收,再转存目标列 - 想跳过某列(比如 CSV 有 5 列,表只要前 3 列)?写成
(col_a, col_b, col_c, @dummy, @dummy),用@dummy占位
为什么明明语法对了却只导入几万行就停了
因为 LOAD DATA INFILE 是“全有或全无”:遇到任何一行格式错误(空字段超长、类型不匹配、引号不闭合),立刻中止,不提示第几行错,也不继续。
- 排查建议:先用
head -n 100 data.csv > test.csv截一小段,手动验证是否能成功;再逐步扩大范围 - 大文件别硬扛:用
split -l 100000 data.csv data_part_拆成 10 万行一份,写个 shell 脚本循环导入,失败只影响单块 - 性能优化可做但别迷信:关唯一键检查(
SET UNIQUE_CHECKS=0)、关自动提交(SET autocommit=0)、关外键(SET FOREIGN_KEY_CHECKS=0)确实有效,但记得导完恢复;DISABLE KEYS对 InnoDB 无效,别白费劲 - 最常被忽略的一点:千万级导入前,确认磁盘 I/O 没瓶颈——SSD 上 1.2GB CSV 导入通常 2–5 分钟;如果跑在机械硬盘或共享云盘上,速度可能断崖下跌,这时拆分 + 并发反而更稳

















