【问题标题】:Hibernate saveAndFlush() takes a long time for 10K By-Row InsertsHibernate saveAndFlush() 10K By-Row Inserts 需要很长时间
【发布时间】:2020-02-16 23:43:54
【问题描述】:

我是 Hibernate 新手。我有以下代码仍然存在于List<String>:

的大量(比如10k)行:
@Override
@Transactional(readOnly = false)
public void createParticipantsAccounts(long studyId, List<String> subjectIds) throws Exception {
    StudyT study = studyDAO.getStudyByStudyId(studyId);
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    for(String subjectId: subjectIds) {  // LOOP with saveAndFlush() for each
        // ...
        user.setRoleTypeId(4);
        user.setActiveFlag("Y");
        user.setCreatedBy(auth.getPrincipal().toString().toLowerCase());
        user.setCreatedDate(new Date());
        List<StudyParticipantsT> participants = new ArrayList<StudyParticipantsT>();
        StudyParticipantsT sp = new StudyParticipantsT();
        sp.setStudyT(study);
        sp.setUsersT(user);
        sp.setSubjectId(subjectId);
        sp.setLocked("N");
        sp.setCreatedBy(auth.getPrincipal().toString().toLowerCase());
        sp.setCreatedDate(new Date());
        participants.add(sp);
        user.setStudyParticipantsTs(participants);
        userDAO.saveAndFlush(user);
    }
   }
}

但是这个操作耗时太长,大概5-10分钟。 10K 行。改善这种情况的正确方法是什么?我真的需要用批量插入重写整件事吗?或者有什么简单的我可以调整?

注意我还尝试了不使用 Flush 的 userDAO.save(),并在 for 循环外的末尾尝试了 userDAO.flush()。但这并没有帮助,同样糟糕的表现。

【问题讨论】:

    标签: spring hibernate jpa spring-data


    【解决方案1】:

    我们解决了。 批量插入使用saveAll 完成。我们定义了一个批量大小,比如 1000,saveAll 列表,然后重置。如果最后(边缘条件)我们也保存。这大大加快了所有插入的速度。

        int batchSize = 1000;
    
        // List for Batch-Inserts
        List<UsersT> batchInsertUsers = new ArrayList<UsersT>();
    
        for(int i = 0; i < subjectIds.size(); i++) {
    
            String subjectId = subjectIds.get(i);   
    
            UsersT user = new UsersT();
            // Fill out the object here...
            // ...
    
            // Add to Batch-Insert List; if list size ready for batch-insert, or if at the end of all subjectIds, do Batch-Insert saveAll() and clear the list
            batchInsertUsers.add(user);
            if (batchInsertUsers.size() == maxBatchSize || i == subjectIds.size() - 1) {
                userDAO.saveAll(batchInsertUsers);
                // Reset list
                batchInsertUsers.clear();
            }
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-16
      • 2015-04-22
      • 1970-01-01
      • 2013-09-07
      • 2020-08-26
      • 2014-10-09
      • 2012-11-26
      相关资源
      最近更新 更多