ERROR 1148需开启local_infile(服务端设ON、客户端加--local-infile=1),ERROR 1290需将文件移至secure_file_priv指定目录再用LOAD DATA INFILE(不含LOCAL)。

LOAD DATA INFILE 是唯一能真正把千万行数据压进秒级导入区间的方案,但 90% 的人卡在权限、路径或索引误操作上,不是命令慢,是没配对。
LOAD DATA INFILE 报 ERROR 1148 或 1290 怎么办
这两个错误本质是 MySQL 拒绝执行文件导入,不是语法错,而是启动态未放开:
-
ERROR 1148:服务端没开local_infile,或客户端连的时候没带--local-infile=1;检查SELECT @@local_infile;必须返回ON -
ERROR 1290:secure_file_priv不为空(比如是/var/lib/mysql-files/),但你传的路径不在该目录下;别改配置清空它,直接把 CSV 放进该目录再用LOAD DATA INFILE(去掉LOCAL) - 云数据库(如阿里云 RDS、AWS RDS)默认禁用
LOCAL INFILE且无法开启——这时只能走 SFTP 上传到服务器本地,再用不带LOCAL的版本
字段类型不匹配导致静默跳过或 ERROR 1366
CSV 字段顺序、类型、NULL 约束必须和表定义完全一致,否则 MySQL 不报错也不提示,只跳过整行:
- 用
head -n 1 data.csv | od -c看真实分隔符,Excel 导出常是;或\t,别硬写FIELDS TERMINATED BY ',' - 含换行符的文本字段(如用户评论)必须加
OPTIONALLY ENCLOSED BY '"',否则 MySQL 把换行当新记录 - 时间字段如
"2024-03-15 14:22:08"直接插DATETIME列会失败,得用SET created_at = STR_TO_DATE(@created_at, '%Y-%m-%d %H:%i:%s') - 空字符串
""插入NOT NULL列会报错,补一句SET col = NULLIF(@col, '')
为什么 SET unique_checks=0 和 DROP INDEX 都要干
InnoDB 表上 ALTER TABLE t DISABLE KEYS 是无效空操作,别信老教程。真正起效的是这两步组合:
- 先关约束:
SET unique_checks = 0;和SET foreign_key_checks = 0;—— 否则每行都触发唯一键校验和外键查找,而你刚删了索引,这些查找就是全表扫描 - 再删非主键索引:
DROP INDEX idx_name ON t1;(主键不能删)—— 边插边维护二级索引比批量重建慢 3–5 倍 - 导入完立刻恢复:
SET unique_checks = 1;触发全表唯一性校验,如果源数据本身有重复,这里会报错;所以清洗必须在导入前完成 - 最后用备份好的 DDL 重建索引,别等查询慢了才想起来建
导入后卡在 COMMIT 或索引重建怎么办
导入语句执行完不代表结束,InnoDB 还在后台刷脏页、合并索引页:
- 导入前调大缓冲区:
SET sort_buffer_size = 256M;、SET bulk_insert_buffer_size = 64M;(根据物理内存设,别超 25%) - 导入时显式控制事务:
SET autocommit = 0;,语句后跟COMMIT;,避免隐式提交拖慢吞吐 - 别在导入中途查
SHOW PROCESSLIST看“是不是卡住了”——LOAD DATA 是单线程同步操作,进度条靠日志或INFORMATION_SCHEMA.INNODB_METRICS查buffer_pool_pages_dirty - 重建索引阶段最耗时,尤其没提前建好关联字段索引时,
foreign_key_checks = 0不跳过索引更新,只是跳过约束检查
真正容易被忽略的是:unique_checks = 0 期间不校验唯一性,但导入后 SET unique_checks = 1 会强制全表扫描校验——这一步可能比导入本身还慢,而且不可中断。数据清洗和索引重建顺序,比 LOAD DATA 语法本身更决定成败。


















