Почему 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
говорит, что может быть штраф за использование этих свойств. Я бы предположил, что это причина, по которой они не установлены по умолчанию.