结论:mysql 8.0 导入百gb级测试数据,load data infile 是唯一现实选择;source 和 mysql 客户端逐行执行 sql 文件本质是串行解析+单条insert,会因sql解析开销、autocommit事务刷盘、网络/内存瓶颈及 max_allowed_packet 限制而卡死、超时或oom,完全无法应对百gb量级。

直接说结论:MySQL 8.0 导入百GB级测试数据,LOAD DATA INFILE 是唯一现实选择;其他方式(如 SOURCE、逐行 INSERT、存储过程)在百GB量级下基本不可用——不是慢,而是会卡死、超时、OOM 或触发系统级限制。
为什么不能用 SOURCE 或 mysql
这些方式本质是把 SQL 文本喂给 MySQL 解析器逐条执行:INSERT 语句本身要解析、权限校验、事务开销、binlog 写入、索引实时更新。百GB SQL 文件往往含数千万到上亿条 INSERT,即使关了 autocommit 和 sql_log_bin,单线程吞吐也卡在几百 MB/h 级别,且极易因 max_allowed_packet 或内存不足中断。
-
SOURCE命令不支持大文件流式读取,全加载进客户端内存,10GB 就可能崩 mysql -u ... db 虽绕过客户端内存,但服务端仍需逐句 parse —— 百GB 文件里可能有上亿个 <code>INSERT,每句都走完整 SQL 生命周期- 即使加了
--max-allowed-packet=1G,也无法规避语法解析和索引维护的硬瓶颈
LOAD DATA INFILE 必须配的 4 个关键设置
LOAD DATA INFILE 绕过 SQL 解析器,直接按二进制格式批量写入 InnoDB buffer pool,是百GB导入的唯一可行路径。但它默认行为仍会拖慢速度,必须同会话设置以下四项:
-
SET autocommit = 0:避免每行自动提交,否则 redo log 刷盘爆炸 -
SET unique_checks = 0:真正提速核心——跳过主键/唯一索引的逐行 B+ 树查找,延迟到导入结束统一校验 -
SET foreign_key_checks = 0:仅当表真有外键时才有效;若无外键,设了也没用 -
SET sql_log_bin = 0:关闭 binlog 写入(仅限测试库!生产禁用),否则sync_binlog=1会强制刷盘,抵消所有优化
注意:这四个 SET 必须在同一个客户端会话中执行,且在 LOAD DATA INFILE 之前;导入完必须立刻恢复为 1,否则后续写入可能静默失败或索引损坏。
secure_file_priv 和 local_infile 的坑怎么绕
导入失败报错 The MySQL server is running with the --secure-file-priv option 是最常见拦路虎。MySQL 8.0 默认只允许从特定目录读文件,不能直接读任意路径。
- 查当前限制:
SHOW VARIABLES LIKE 'secure_file_priv',返回值如/var/lib/mysql-files/就只能把 CSV 放这里 - 不要改
secure_file_priv = ""—— 这在云数据库(RDS/Aurora)上根本不可行,且重启生效,运维成本高 - 正确做法:把数据文件拷到
secure_file_priv指向的目录,然后用绝对路径调用,例如:LOAD DATA INFILE '/var/lib/mysql-files/large_data.csv' ... - 如果要用
LOAD DATA LOCAL INFILE(从客户端读本地文件),必须启动 MySQL 客户端时加--local-infile=1,且服务端local_infile变量为ON(SET GLOBAL local_infile = 1),但部分托管服务禁止此功能
字符集、NULL 和日期字段的隐形雷区
百GB数据里只要有一行字段格式不对,整个 LOAD DATA INFILE 就会停在那行报错,且默认不提示具体哪一行出问题。
- 中文乱码?确认 CSV 是
UTF8MB4编码,并在LOAD语句末尾加CHARACTER SET utf8mb4 - 某列该是
NULL却写了空字符串?用SET col_name = NULLIF(@col_name, '')在字段映射里转换 - 时间字段带毫秒(如
"2025-01-01 12:34:56.789")?MySQL 8.0 的DATETIME(3)支持,但需确保字段定义匹配,否则截断或报错;更稳妥是导入前用awk或sed预处理 - 首行是标题?必须加
IGNORE 1 ROWS,否则第一行会被当数据插进去,类型错配直接中断
真正难的从来不是“怎么快”,而是“怎么稳”——百GB导入一旦中断,重试成本极高;务必先用小样本(如 10MB)验证字段映射、编码、约束是否全部对齐,再跑全量。











