LOAD DATA INFILE 比单条 INSERT 快得多,因其绕过 SQL 解析、权限校验与完整执行流程,直接批量构造内存行并刷入引擎,减少 redo log 刷盘、锁竞争及网络开销;但需注意路径、编码、LOCAL 开关等配置,否则易报错或乱码。

LOAD DATA INFILE 绕过了 SQL 解析和权限校验
单条 INSERT 每执行一次,MySQL 都要走完整 SQL 生命周期:词法/语法解析、语义检查、权限验证、生成执行计划、写 binlog / redo log / undo log、更新索引 B+ 树。百万次就是百万遍。而 LOAD DATA INFILE 是服务端原生批量导入机制,它直接读取文件内容,按行切分、字段解析、构造内存行对象,再批量刷入存储引擎——不走 parser,不查权限表,也不经过 query cache 或 optimizer。
事务与日志刷盘开销差异极大
默认 autocommit=1 时,每条 INSERT 都是独立事务,必须同步刷 redo log 到磁盘(尤其当 innodb_flush_log_at_trx_commit=1)。而 LOAD DATA INFILE 在内部以大批次方式组织写入,redo log 可合并刷盘,锁竞争也大幅降低。实测百万行插入:LOAD DATA INFILE 常在 5–10 秒完成;等量分批 INSERT 即使加事务包裹,也常需 60 秒以上。
网络往返与驱动层开销被彻底消除
应用层用 JDBC 或 PyMySQL 执行 INSERT,哪怕开了 rewriteBatchedStatements=true,仍需序列化语句、经网络传输、服务端反序列化、再进执行器。而 LOAD DATA INFILE 只发一条 SQL 命令,后续全部由 MySQL 进程自己读磁盘文件完成,不依赖客户端内存或网络带宽。如果你的数据源本来就是 CSV 文件,走 LOAD DATA 几乎不占 JVM 堆或 Python GC 压力。
容易踩的坑:路径、编码、LOCAL 模式开关
常见错误包括:
-
ERROR 1148: The used command is not allowed with this MySQL version→ 服务端未启用local_infile,或客户端连接没加--local-infile参数 -
ERROR 29: File '/path/data.csv' not found→ 服务端模式下文件不在secure_file_priv目录内,或 MySQL 进程用户无读取权限 - 中文乱码 → 必须显式指定
CHARACTER SET utf8mb4,不能依赖连接默认编码 - 字段错位 → CSV 中含逗号或换行符时,必须用
ENCLOSED BY '"'包裹字段,且LINES TERMINATED BY '\n'要严格匹配实际换行符
真正快的前提,是文件位置、权限、格式、编码全对齐——少一个,就退化成报错或脏数据,而不是变慢。











