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