领导今天安排了个任务, 涉及到大批量数据的插入 , 最开始使用的是 mybatis 的simple 模式 , 性能不咋地 , 于是脑洞打开考虑使用 batch 了 , 所以就开始搭建环境测试 , 代码如下 :
@Autowired
protected SqlSessionFactory sqlSessionFactory;
//batch 模式
// 插入 7999 条 耗时 : 4074
// 插入 15000 条 耗时 : 6690
// 插入 20000 条 耗时 : 7024
@Test
public void testBatchInsert() {
//在会话中切换 batch 模式
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
TdBaseTradeRightMapper tdBaseTradeRightMapper = sqlSession.getMapper(TdBaseTradeRightMapper.class);
List<TdBaseTradeRight> tdBaseTradeRightList = new ArrayList<>();
//创建 20000条数据
for (int i = 0; i < 20000; i++) {
TdBaseTradeRight tdBaseTradeRight = new TdBaseTradeRight();
tdBaseTradeRight.setTradeVarietyId("42ed4cc508854a02ab7c2e050ff9cb03");
//...
tdBaseTradeRightList.add(tdBaseTradeRight);
}
// 开始批量插入
try {
Long start = System.currentTimeMillis();
// 这里必须高度重视 ,循环里面访问mysql插入,必须指定 batch模式,否则性能爆炸 !!!
tdBaseTradeRightList.stream().forEach(item -> tdBaseTradeRightMapper.insertBatch(item));
sqlSession.commit(); // 提交事务
Long end = System.currentTimeMillis();
System.out.println("耗时 : " + (end - start));
} catch (Exception e) {
sqlSession.rollback();//回滚事务
e.printStackTrace();
} finally {
sqlSession.close();
}
}
刚开始性能测试的时候 , 插入性能竟然超级慢! 慢! 慢! , 比用 foreach 批量插入还慢 , 这就有点违背现实常理了, 理论上batch 插入 应该比 foreach 更快的 , 所以考虑应该是没有正确开启batch模式 ;
后来查阅了相关资料后 , 终于发现了造成性能慢的原因 , 原来是连接数据库的会话必须指定批量插入参数, 就是在jdbc连接参数的url添加参数 rewriteBatchedStatements=true , 如下
温馨提示 : 嘿嘿 , 图中的是内网项目 , 所以ip , 用户 就不打码啦 , 各位大佬不用慌哈 ;
最后总结: mybatis 设置 batch模式后 , 如果插入性能很慢 , 有可能是在设置jdbc连接参数会话时候, 没有加上允许批量插入参数 rewriteBatchedStatements=true ; ok , 搞定收工 , bug 解决 .
最后祝各位兄弟bug越写越少 , 头发越来越茂盛 .