Я испытываю затруднения при получении, в спящем режиме для выполнения объемной вставки на MySQL.
Я использую, в спящем режиме 3.3 и MySQL 5.1
На высоком уровне это - то, что происходит:
@Transactional
public Set<Long> doUpdate(Project project, IRepository externalSource) {
List<IEntity> entities = externalSource.loadEntites();
buildEntities(entities, project);
persistEntities(project);
}
public void persistEntities(Project project) {
projectDAO.update(project);
}
Это приводит к n записям в журнале (1 для каждой строки) следующим образом:
Будьте в спящем режиме: вставьте в ProjectEntity (имя, parent_id, путь, project_id, состояние, введите) значения (??????)
Я хотел бы видеть, что это обрабатывается в пакетном режиме, таким образом, обновление более производительно. Возможно, что эта стандартная программа могла привести к десяткам тысяч строк, сгенерированных, и прохождение дб на строку является уничтожителем.
Почему это не обрабатывает в пакетном режиме? (Это - мое понимание, что пакет вставляет, как, предполагается, значение по умолчанию в соответствующих случаях, в спящем режиме).
Как описано в Глава 13. Пакетная обработка:
Если вы осуществляете пакетную обработку, вам необходимо включить использование пакетной обработки JDBC. Это абсолютно необходимо, если вы хотите достичь оптимальной производительности. Установите размер пакета JDBC на разумное число (например, 10-50):
hibernate.jdbc.batch_size 20
Hibernate отключает пакетную вставку на на уровне JDBC прозрачно, если вы используете генератор идентификаторов.
Не забывайте регулярно flush
и затем clear
сессию, иначе вы получите OutOfMemoryException
, как описано в 13.1. Пакетные вставки.
Но IMO, для десятков тысяч строк, вы должны рассмотреть возможность использования интерфейса StatelessSession
.
Паскаль в значительной степени прибил это в контексте гибернации. В качестве альтернативы вы можете использовать Batchsqlupdate шаблона jbdc. Однако я должен предупредить вас, что кешированные экземпляры спящего режима могут не отражать изменения, сделанные с использованием выше. В нашем проекте нам пришлось принять меры предосторожности, чтобы преодолеть это, создав другой график (возникла еще одна проблема, но под нашим контролем)
Ответ Паскаля правильный. Однако, поскольку вы используете MySQL, я также настоятельно рекомендую вам попробовать использовать параметр rewriteBatchedStatements=true
в вашем JDBC URL.
Этот параметр заставляет драйвер JDBC динамически переписывать ваши INSERT-пакеты, чтобы использовать один "многозначный" INSERT, например:
INSERT INTO mytable (mycol) VALUES (0);
INSERT INTO mytable (mycol) VALUES (1);
INSERT INTO mytable (mycol) VALUES (2);
будет переписан в:
INSERT INTO mytable (mycol) VALUES (0), VALUES (1), VALUES (2);
Это может иметь существенное значение в некоторых случаях. Примеры измерений см. на http://www.jroller.com/mmatthews/entry/speeding_up_batch_inserts_for.