Мне нужно вставить 60К строк в базу данных Postgres в моем приложении Java / Spring с использованием данных Hibernate / Spring.
Входящие данные INSERT: (1) USERS_T, (2) связанные новые пользователи также должны быть в STUDY_PARTICIPANTS_T. Оба они предназначены для записей по 60 КБ.
Ниже работает, но производительность низкая: 60 К занимает 2 минуты. Обратите внимание, что я заполняю сущность Hibernate, а затем выполняю saveAll
на основе списков размером 1000.
UsersT user = new UsersT();
user.setUsername(study.getAbbreviation().toUpperCase()+subjectId);
user.setRoleTypeId(new LookupT(150));
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");
participants.add(sp);
user.setStudyParticipantsTs(participants);
// 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() == 1000 || i == subjectIds.size() - 1) {
// Log this Batch-Insert
if(log.isDebugEnabled()){
log.debug("createParticipantsAccounts() Batch-Insert: Saving " + batchInsertUsers.size() + " records");
}
userDAO.saveAll(batchInsertUsers);
// Reset list
batchInsertUsers.clear();
}
Я нашел поток, в котором у кого-то возникла та же проблема, и единственное решение, которое он нашел, - это создать собственный Native- SQL INSERT (..), (..), (..)
строка для каждого куска 1000, и запустите его вручную, полностью вырезав слой ORM / Hibernate: Нужно вставить 100000 строк в mysql, используя режим гибернации менее чем за 5 секунд
Но мой Вставки включают в себя несколько соединенных таблиц. Я мог бы потратить время на то, чтобы переписать все эти операторы сущностей в пользовательский SQL, но это было бы не просто.
Есть ли другие решения? Я использую - Spring 5.0.2 - Hibernate5.2.12