LOAD DATA INFILE 比逐条 INSERT 快 5–20 倍,因其绕过 SQL 解析、权限校验和单条事务开销,直接走 InnoDB 底层批量写入;而 INSERT 每条均需完整语句生命周期及独立索引维护。

直接用 LOAD DATA INFILE,别写循环 INSERT —— 后者慢 5–20 倍是常态,不是夸张。
为什么 LOAD DATA INFILE 比逐条 INSERT 快那么多
它绕过 SQL 解析、权限校验(部分)、单条事务开销,直接走 InnoDB 底层批量写入路径。而逐条 INSERT 每次都要走完整语句生命周期:词法解析 → 权限检查 → 生成执行计划 → 写 binlog → 写 redo log → 提交事务。
常见错误认知是“只要加事务就差不多”,但即使 START TRANSACTION; INSERT ...; INSERT ...; COMMIT;,每条 INSERT 仍要单独触发索引维护、约束检查、行锁获取 —— 这些开销在千万级下会指数放大。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 千万行 CSV(约 1.2GB)在 SSD + 关闭唯一键检查时,
LOAD DATA INFILE通常 2–5 分钟;同等INSERT可能要 1–2 小时 - 如果用了
mysqlclient或pymysql,默认不启用LOCAL INFILE,连命令都执行不了,报错The used command is not allowed with this MySQL version -
LOAD DATA INFILE要求文件在数据库服务器磁盘上,且 MySQL 进程有读权限;LOAD DATA LOCAL INFILE才走客户端,但需服务端和客户端双侧显式开启
LOAD DATA INFILE 字段映射和分隔符配置要点
字段对不上、数据截断、空值乱入,90% 不是语法错,而是分隔逻辑没对齐。
- 用
FIELDS TERMINATED BY ','时,确保 CSV 中没有未转义的逗号(比如地址字段 “北京市,朝阳区”);必须配ENCLOSED BY '"',否则会把一行切碎 - Windows 生成的 CSV 默认换行是
\r\n,LINES TERMINATED BY '\n'会导致最后一列多出\r,应改为LINES TERMINATED BY '\r\n' - 字段顺序必须和表结构严格一致;若要跳过某列(如 CSV 多一列时间戳),用
LOAD DATA INFILE '/tmp/data.csv' INTO TABLE t1 (col_a, col_b, @dummy, col_c),其中@dummy是用户变量,不写入表 - 时间字段如
"2024-03-15 14:22:08"不能直插,得用SET created_at = STR_TO_DATE(@created_at, '%Y-%m-%d %H:%i:%s')
导入前必须调的几个关键配置项
不调这些,LOAD DATA INFILE 的性能优势会被吃掉大半。
- 禁用索引:
ALTER TABLE your_table DISABLE KEYS;导入完再ENABLE KEYS;—— 否则每插一行都重建索引,速度跌回INSERT级别 - 关掉日志刷盘:
SET SESSION innodb_flush_log_at_trx_commit = 0;(仅当前会话),避免每次提交都强制刷盘;生产环境慎用全局设置 - 加大缓存:
SET SESSION bulk_insert_buffer_size = 512 * 1024 * 1024;(512MB),对 MyISAM 表尤其有效;InnoDB 下效果有限但无害 - 增大包上限:
SET SESSION max_allowed_packet = 128 * 1024 * 1024;(128MB),防大字段或长行报错Packets larger than max_allowed_packet bytes are not allowed
容易被忽略的失败原因和排查点
报错退出却不提示哪一行出问题,是 LOAD DATA INFILE 最让人抓狂的地方。
- 格式错误(如引号嵌套、换行符混用、空值写成
NULL但字段非 NULL)会直接中止,且不输出具体行号 —— 建议先用head -n 100 data.csv | cat -A查看不可见字符 - 权限问题常被误判为路径错:
LOAD DATA INFILE只能读 MySQL 服务端能访问的路径(如/var/lib/mysql-files/),不是你本地电脑的~/Downloads/ - 云数据库(如阿里云 RDS、腾讯云 CDB)默认禁用
LOCAL INFILE,且不开放DISABLE KEYS权限,LOAD DATA INFILE也受限 —— 此时只能退到多值INSERT+ 分批事务 - 导入后务必执行
ANALYZE TABLE your_table;,否则优化器可能还用旧统计信息,后续查询走错索引

















