在处理业务系统初始化或日常运营时,将Excel中的数据导入Mysql是非常普遍的需求。当数据量较小时,简单的逐行插入不会暴露问题;但一旦达到几万或上百万行,大批量插入往往会引发执行缓慢、连接超时、内存占用过高等状况。理解这些问题的根源并采用合适的导入方式,是保障数据迁移效率的关键。

为什么大批量插入Excel数据会变慢
大多数初学者在导入Excel时,会先解析每行记录,然后循环调用单条insert语句。这种方式在Mysql中会带来明显的性能瓶颈:
- 每条insert都要经历网络传输、语法解析、事务日志写入等过程,行数越多开销越大。
- 如果未显式开启事务,Mysql默认自动提交,导致磁盘刷盘频率极高。
- 在代码中一次性读取全部Excel行到内存,容易引发内存溢出。
- 表上若存在多个索引,每插入一行都要维护索引结构,拖累写入速度。
使用LOAD DATA INFILE直接导入
Mysql原生的LOAD DATA INFILE命令可以跳过SQL层解析,将文本文件高效写入表。我们可以把Excel先转为CSV,再用该命令加载。
-- 将Excel另存为data.csv后执行 LOAD DATA INFILE '/tmp/data.csv' INTO TABLE user_info CHARACTER SET utf8mb4 FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY 'n' IGNORE 1 LINES (column_name, age, created_at);
如果Mysql服务与文件不在同一台机器,可使用LOAD DATA LOCAL INFILE,但需在连接时开启本地文件读取权限。
多值INSERT配合事务
当无法使用文件加载时,可以采用每次拼接多行值的insert,并放在一个事务里提交。
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.List;
public class ExcelImporter {
public void batchInsert(Connection conn, List<String[]> rows) throws Exception {
// 关闭自动提交,改为手动控制事务
conn.setAutoCommit(false);
String sql = "INSERT INTO user_info(name, age) VALUES (?, ?)";
PreparedStatement ps = conn.prepareStatement(sql);
int count = 0;
for (String[] row : rows) {
ps.setString(1, row[0]);
ps.setInt(2, Integer.parseInt(row[1]));
ps.addBatch();
// 每满1000条执行一次批处理
if (++count % 1000 == 0) {
ps.executeBatch();
}
}
ps.executeBatch();
conn.commit();
ps.close();
}
}
其他实用优化建议
| 问题场景 | 应对方式 |
|---|---|
| 导入期间索引拖慢写入 | 先移除非唯一索引,导入完成后再重建 |
| Excel含有特殊字符 | 统一字符集为utf8mb4并做转义 |
| 连接频繁超时 | 调大net_write_timeout与max_allowed_packet |
小结
面对Excel大批量导入Mysql,优先选择LOAD DATA INFILE;受限环境下使用批处理加事务。同时配合索引临时关闭和参数调优,即可稳定高效地完成数据迁移。
Excel导入Mysql大批量插入LOAD_DATA_INFILE修改时间:2026-07-26 19:18:20