JPA批量插入优化


遇到一个需求是excel数据导入,一次大概会批量插入几万的数据。写完一测奇慢无比。

于是开始打日志,分析代码,发现是插入数据库的时候耗时很长,发现是spring data jpa的原因。

翻看jpa的源码

 

@Transactional
    public <S extends T> List<S> saveAll(Iterable<S> entities) {

        Assert.notNull(entities, "The given Iterable of entities not be null!");

        List<S> result = new ArrayList<S>();

        for (S entity : entities) {
            result.add(save(entity));
        }

        return result;
    }

 

这里会循环对每个对象进行save操作,看到这里问题也大概清楚了,多次insert操作。

再看看save操作

 1     @Transactional
 2     public <S extends T> S save(S entity) {
 3 
 4         if (entityInformation.isNew(entity)) {
 5             em.persist(entity);
 6             return entity;
 7         } else {
 8             return em.merge(entity);
 9         }
10     }

保存的时候,会对对象做存在性检查,就是先查一边,要是不存在才会保存。

 

优化方案有很多种,但是要从根本上解决这个问题,就要避免jpa 的多次保存和存在性检查,才能减少数据库的交互。

最后选用的是spring data jpa和spring jdbc组合使用,jpa大量的写入就用sprng jdbc。

另外,在数据库地址上加上

rewriteBatchedStatements=true 开启批量写入

因为spring jdbc 和spring boot 的兼容性很好,基本不需要什么配置,另外spring jdbc 的namedParameterJdbcTemplate.batchUpdate对批量插入编写sql也比较快捷。

优化之后比之前减少90%的时间,看来jpa是真不适合数据量稍大的系统,需要和其他框架配合使用才行。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM