Почему Hibernate batching / order inserts / order updates отключен по умолчанию?

есть ли причины, по которым Hibernate batching / hibernate.order_updates / hibernate.order_inserts отключены по умолчанию? Есть ли недостаток при включении размер пакета 50? Же для order_updates / параметры order_inserts. Есть ли вариант использования, в котором вы не должны включать эти функции? Есть ли какие-либо последствия для производительности при использовании этих функций?

Я вижу, что эти настройки очень помогают, когда мне нужно уменьшить количество запросов, которое необходимо особенно в облачной среде с большими задержками между моим приложением и сервером базы данных.

2 ответов


как правило, параметр batch size к resonable размеру и order_insert, order_updates to true может значительно повысить производительность.

во всех моих проектах я использую эту конфигурацию в качестве основы:

hibernate.jdbc.batch_size = 100
hibernate.order_inserts   = true 
hibernate.order_updates   = true
hibernate.jdbc.fetch_size = 400

а, да - не может быть влияние памяти при использовании пакетирования. Но это зависит от драйвера JDBC.

например драйвер Oracle JDBC создает внутренние буферы для каждого PreparedStatement и использует эти буферы. Если вы называете простой инструкция update вы устанавливаете некоторые параметры с помощью ps.setInt(1, ...), ps.setString(2, ...) etc, и Oracle преобразует эти значения в некоторое байтовое представление и сохраняет в буфере, связанном с этим PreparedStatement и соединение.

когда PreparedStatement использует партию размера 100, этот буфер будет в 100 раз больше. И если у вас есть пул соединений с соединениями exapmle 50, может быть 50 таких больших буферов. И если у вас есть 100 различных операторов, использующих пакетирование, все такие буферы могут иметь значительное влияние на память. Когда вы включаете размер пакета, он становится глобальным - Hibernate будет использовать его для всех вставок / обновлений.

однако я обнаружил, что во всех моих проектах увеличение производительности было более важным, чем это влияние памяти, и поэтому я использую batchsize=100 по умолчанию.

С order_inserts, order_updates, Я думаю, что они отключены по умолчанию, потому что эти настройки имеют смысл только тогда, когда пакетирование включено. С дозировать set off, эти приказывать просто накладные расходы.

вы можете найти более подробную информацию в Белой книге Oracle:

http://www.oracle.com/technetwork/topics/memory.pdf

в разделе "пакетирование инструкций и использование памяти".

==== редактировать 2016.05.31 ====

несколько слов о order_inserts и order_udpates собственность. Допустим, у нас есть сущности A, B и сохраняйте 6 объектов таким образом:

session.save(A1);  // added to action queue
session.save(B1);  // added to action queue
session.save(A2);  // ...
session.save(B2);  // ...
session.save(A3);  // ...
session.save(B3);  // ...

после выше исполнение:

  • эти 6 объектов имеют идентификаторы, сгенерированные
  • эти 6 объектов подключены к сеансу (StatefulPersistenceContext:entitiesByKey, entityEntries и др. /ХИБ.v3/)
  • эти 6 объектов добавляются в ActionQueue в том же порядке: [A1, B1, A2, B2, A3, B3]

теперь рассмотрим 2 случая:

Пример 1: order_inserts = false

во время полной фазы hibernate выполняет 6 вставить отчетность:

ActionQueue = [A1, B1, A2, B2, A3, B3]
insert into A - (A1)
insert into B - (B1)
insert into A - (A2)
insert into B - (B2)
insert into A - (A3)
insert into B - (B3)

Пример 2: order_inserts = true, дозирование допускается

теперь, во время полной фазы hibernate выполняет 2 пакетная вставка отчетность:

ActionQueue = [A1, A2, A3, B1, B2, B3]
insert into A -  (A1, A2, A3)
insert into B -  (B1, B2, B3)

я исследовал это для Hibernate v3, я думаю, что Hibernate v4 использует ActionQueue таким же образом.


документация здесь: https://docs.jboss.org/hibernate/stable/orm/userguide/html_single/chapters/batch/Batching.html

говорит, что может быть штраф за использование этих свойств. Я бы предположил, что это причина, по которой они не установлены по умолчанию.