悠悠楠杉
MyBatis批量插入数据的深度性能优化实践
MyBatis批量插入数据的深度性能优化实践
在实际开发中,批量数据插入是常见的业务场景。当我们需要向数据库一次性插入大量数据时,传统的单条插入方式往往会导致性能瓶颈。本文将深入探讨MyBatis框架下的批量插入优化方案。
一、常规批量插入的性能痛点
先来看一个典型反例——循环单条插入:
java
for(User user : userList) {
sqlSession.insert("com.example.insertUser", user);
}
这种方式存在三个致命问题:
1. 每次插入都需建立/释放数据库连接
2. SQL语句反复解析编译
3. 网络IO次数与数据量成正比
测试数据显示:插入1万条记录耗时约45秒,TPS仅为222条/秒。
二、MyBatis批量插入的优化方案
方案1:foreach动态SQL拼接
xml
<insert id="batchInsert">
INSERT INTO users(name,age) VALUES
<foreach collection="list" item="user" separator=",">
(#{user.name},#{user.age})
</foreach>
</insert>
优化效果:
- 单次SQL执行
- 网络IO降至1次
- 1万条记录耗时降至3.2秒
注意事项:
- 数据量过大可能导致SQL超长
- 建议单批不超过1000条
方案2:ExecutorType.BATCH模式
java
try(SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
UserMapper mapper = session.getMapper(UserMapper.class);
for(User user : userList) {
mapper.insert(user);
}
session.commit();
}
底层原理:
- JDBC的addBatch()机制
- 预编译SQL复用
- 延迟执行flushStatements
性能对比:
- 传统模式:1万条/45秒
- BATCH模式:1万条/1.8秒
方案3:多线程批量提交
java
// 分片处理
List<List
// 并行处理
partitions.parallelStream().forEach(batch -> {
try(SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
batch.forEach(user -> session.insert("insertUser", user));
session.commit();
}
});
关键参数:
- 分片大小:500-2000条/批
- 线程数:建议CPU核心数×2
三、进阶优化技巧
1. JDBC参数调优
properties
rewriteBatchedStatements=true
allowMultiQueries=true
useServerPrepStmts=true
MySQL开启批处理模式后,1万条插入可优化至0.9秒。
2. 事务控制优化
java
// 每1000条提交一次
for(int i=0; i<userList.size(); i++){
if(i>0 && i%1000==0){
sqlSession.commit();
sqlSession.clearCache();
}
mapper.insert(userList.get(i));
}
3. 对象转换优化
java
// 禁用ORM映射
@Options(useGeneratedKeys=false)
@InsertProvider(type=UserSqlProvider.class, method="batchInsert")
void rawBatchInsert(@Param("list") List<User> users);
四、性能对比测试
| 方案 | 1万条耗时 | TPS |
|---------------------|----------|-----------|
| 单条插入 | 45s | 222 |
| foreach拼接 | 3.2s | 3,125 |
| BATCH模式 | 1.8s | 5,555 |
| 多线程+BATCH | 0.9s | 11,111 |
五、选型建议
- 数据量<500:foreach方案
- 500-5000:纯BATCH模式
- >5000:多线程分片+BATCH
- 超大数据量:考虑使用LOAD DATA INFILE
结语
MyBatis批量插入的优化本质上是减少网络IO和SQL解析开销。实际项目中需要根据数据量、数据库类型、硬件配置等因素综合选择方案。建议在预发布环境进行多方案压测,选择最适合当前业务场景的优化方式。