Стратегии деления на пакеты данных#
Объекты в таблице можно разделить на пакеты данных несколькими способами. В зависимости от модели и объема таблицы оптимальными могут быть различные способы. За деление отвечает функциональность стратегий деления на пакеты данных.
Стратегия Hashcode#
Принцип деления на пакеты данных основан на вычислении хеш-кода идентификатора объекта, деленного на количество пакетов данных. Остатком от деления будет номер пакета данных, в который попадает объект.
Преимущества стратегии:
Во вспомогательную таблицу записывается только количество пакетов данных для каждой сущности, что гарантирует ее небольшой объем.
Работает одинаково для различных типов БД.
Работает как с составными, так и простыми ключами.
Работает с ключами типа uuid.
Недостатки стратегии:
При каждом запросе пакета данных в БД происходит полное сканирование таблицы и вычисляется хеш первичного ключа. Это приводит к большой утилизации БД и делает Init больших таблиц невозможным
Не поддерживаются лимиты.
Стратегия SimpleId#
Принцип деления основан на разбивке таблицы на равные пакеты данных, отсортированные по первичному ключу. Диапазоны пакетов данных записываются во вспомогательную таблицу на этапе подготовки. На этапе загрузки пакет данных выбирается по диапазону ключей.
Преимущества стратегии:
При запросе каждого пакета данных происходит поиск по индексу, что не приводит к большой утилизации БД.
Деление на пакеты данных происходит в результате исполнения небольшого количества OLAP запросов.
Поддерживает лимиты по количеству и по значению.
Работает с ключами типа uuid.
Недостатки стратегии:
Во вспомогательной таблице хранится большой объем данных, приблизительно равный количеству строк в таблице, деленному на размер пакета данных.
Работает только с простыми ключами.
Имеет различную реализацию для Oracle и Postgresql.
Стратегия CompositeId#
Принцип деления основан на записывании во вспомогательную таблицу полного списка ключей объектов, входящих в состав пакета данных. На этапе подготовки происходит полное чтение таблицы с последующей вставкой списков ключей во вспомогательную таблицу. Разбиение на пакеты данных происходит в коде библиотеки, на стороне Приложения. На этапе загрузки пакет данных выбирается по списку ключей.
Преимущества стратегии:
При запросе каждого пакета данных происходит поиск по индексу, что не приводит к большой утилизации БД.
Поддерживает лимиты по количеству и по значению.
Работает одинаково для различных типов БД.
Работает как с составными, так и простыми ключами.
Работает с ключами типа uuid.
Недостатки стратегии:
Во вспомогательной таблице хранится большой объем данных, приблизительно равный количеству строк в таблице, деленному на размер пакета данных.
Обработка деления на пакеты данных ведется на стороне Приложения, вследствие чего узким местом становится jdbc-соединение.
На этапе загрузки генерируется запрос с длинной частью условия, что при большом размере пакета данных приводит к StackOverflow исключению в алгоритме Hibernate-критерий. (Внимание! Ошибка не является зацикливанием, возникает вследствие недостаточного размера Java стека в конфигурации Приложения).
Стратегия содержит параметры для тонкой настройки стадии подготовки:
setInsertBatchSize(int insertBatchSize) - количество пакетов данных, вставляемых во вспомогательную таблицу за один раз. По умолчанию - 50.
setInitialFetchSize(int initialFetchSize) - размер окна при чтении таблицы сущности, по которой запущен Init. По умолчанию 20000.
Параметры по умолчанию усредненные, в целом дают оптимальное быстродействие, однако на этапе нагрузочного тестирования можно подбирать их индивидуально, в зависимости от размеров пакета данных и используемой модели.
Стратегия CompositeIdBigTable#
Принцип деления основан на сортировке таблицы по двум компонентам первичного ключа и записыванию диапазонов во вспомогательную таблицу. На этапе загрузки чтение таблицы происходит по диапазону компонента первичного ключа.
Преимущества стратегии:
При запросе каждого пакета данных происходит поиск по индексу, что не приводит к большой утилизации БД.
Деление на пакеты данных происходит в результате исполнения небольшого количества OLAP запросов. Как следствие эта стратегия работает быстрее, чем CompositeId.
Не генерирует длинную часть условия на этапе загрузки для любого размера пакета данных. В результате чего не требует большого размера Java-стека.
Недостатки стратегии:
Работает только с составными ключами.
Работает только на БД типа Oracle.
Не работает с ключами типа uuid.
Требует сложной настройки для каждой сущности, вследствие чего может потребовать использование механизма индивидуальных стратегий.
Размер пакета данных может значительно отличаться от пакета к пакету.
Не поддерживает лимиты.
Стратегии BigDecimalField и LongField#
Принцип деления основан на вычислении диапазона записей арифметически по номеру запрошенного пакета данных и его размеру.
На этапе загрузки происходит поиск по числовому полю, заданному пользователем (через метод HibernateDataProviderFactory#setPartitioningFieldName).
Неважно, является ли это поле первичным ключом, однако для сохранения производительности поле должно быть индексировано.
BigDecimalField предназначена для поля типа BigDecimal, LongField - для поля типа BigInteger. Несоответствие стратегии типу поля влияет на производительность стратегии, так как при неправильном выборе в запрос добавляется операция приведения типа, что приводит к полному сканированию вместо поиска по индексу.
Преимущества стратегии:
При запросе каждого пакета данных происходит поиск по индексу, что не приводит к большой утилизации БД (при соблюдении рекомендаций).
Не использует вспомогательную таблицу.
Работает как с составными, так и простыми ключами (т.к. производит поиск по любому указанному полю).
Работает одинаково для различных типов БД.
Отсутствует деление на пакеты данных на этапе подготовки.
Не генерирует длинную часть условия на этапе загрузки для любого размера пакета данных. В результате чего не требует большого размера Java-стека.
Поддерживает лимит по значению (при условии указания для лимита того же поля, что и в настройке стратегии).
Недостатки стратегии:
Требует указания поля. Вследствие чего может потребовать использование механизма индивидуальных стратегий.
Фактический размер пакета данных может отличаться, вплоть до отправки пустых пакетов данных.
Стратегия Autoselect#
Стратегия обертка. В зависимости от типа ключа у сущности выбирает стратегию CompositeId или SimpleId. Все преимущества и недостатки наследуются от используемых стратегий.
Стратегия ManualSelect#
Стратегия обертка для реализации механизма индивидуальных стратегий. Подробнее в Настройка индивидуальной стратегии деления на пакеты данных для определенной сущности.