LOAD DATA INFILE 不报错的关键是将文件置于 secure_file_priv 指定目录(如 /var/lib/mysql-files/),并确保 MySQL 进程有读权限;若远程导入可用 LOAD DATA LOCAL INFILE,但需服务端开启 local_infile=ON 且客户端加 --local-infile=1 参数。

LOAD DATA INFILE 语句怎么写才不报错
直接用 LOAD DATA INFILE 是 MySQL 批量导入最快的方式,但默认会因安全限制报错:ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option。根本原因是 MySQL 只允许从 secure_file_priv 指定目录读取文件。
实操建议:
- 先查当前允许路径:
SHOW VARIABLES LIKE 'secure_file_priv';,返回空值或/var/lib/mysql-files/都得按它来放文件 - 把 CSV 文件(如
data.csv)拷到该目录下,确保 MySQL 进程有读权限(Linux 下常用sudo chown mysql:mysql /var/lib/mysql-files/data.csv) - 建好目标表(字段顺序、类型需与 CSV 列严格对应),再执行导入:
LOAD DATA INFILE '/var/lib/mysql-files/data.csv' INTO TABLE users FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;
- 如果本地客户端连接远程 MySQL,
LOAD DATA LOCAL INFILE可绕过服务端路径限制,但需服务端开启local_infile=ON,且客户端连接时加--local-infile=1参数
用 INSERT INTO ... VALUES 批量插入时性能卡在哪
单条 INSERT 插 10 万行可能耗时几分钟;合并成一条多值 INSERT 能提速 5–10 倍,但不是越长越好。
关键限制和调优点:
- 受
max_allowed_packet控制,超限会报错:Packets larger than max_allowed_packet are not allowed。可临时调大:SET GLOBAL max_allowed_packet = 256*1024*1024;(256MB) - 单条语句建议控制在 1000–5000 行之间,再大容易触发锁等待或事务日志压力
- 务必在事务中执行:
START TRANSACTION; INSERT INTO logs (ts, level, msg) VALUES (...),(...),(...); INSERT INTO logs (ts, level, msg) VALUES (...),(...),(...); COMMIT;
否则每条INSERT都是独立事务,I/O 开销爆炸 - 导入前可临时关闭唯一键检查:
SET UNIQUE_CHECKS=0;,导入后再开;但仅适用于确认数据无冲突的场景
mysqlimport 工具和 LOAD DATA 有什么实质区别
mysqlimport 就是 LOAD DATA INFILE 的命令行封装,本质调用相同服务端逻辑,**不是替代方案,而是快捷写法**。
常见误用和注意点:
- 表名由文件名自动推断(
users.csv→ 导入到users表),必须确保表已存在且字段匹配,否则报错:mysqlimport: Error: Table 'test.users' doesn't exist - 默认以 tab 分隔,不是逗号 —— 如果用 CSV,必须显式指定:
mysqlimport --fields-terminated-by=',' --lines-terminated-by='\n' --ignore-lines=1 test /path/to/data.csv - 不支持字段映射(比如 CSV 第3列要插进表的第1列),这种需求只能退回
LOAD DATA INFILE+SET子句手动赋值 - 和
LOAD DATA一样受secure_file_priv限制,不能直接读任意路径
遇到中文乱码或日期解析失败怎么办
批量导入后发现中文变问号、时间全成 0000-00-00,大概率是字符集或格式没对齐。
定位和修复步骤:
- 确认源 CSV 文件编码:用
file -i data.csv(Linux)或 VS Code 底部右下角看,必须是utf-8或gbk;非 UTF-8 的 CSV 要先转码,别硬导 - 建表时显式指定字符集:
CREATE TABLE users (name VARCHAR(100)) CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - 在
LOAD DATA中声明输入编码:LOAD DATA INFILE '...' CHARACTER SET utf8mb4 INTO TABLE ... - 日期列若为
'2024/05/20'格式,MySQL 默认不认,得用STR_TO_DATE()转换:LOAD DATA INFILE '...' INTO TABLE events (@date_str, title, content) SET created_at = STR_TO_DATE(@date_str, '%Y/%m/%d');










