Подтвердить что ты не робот

Hibernate Subselect vs Batch Fetching

Hibernate предоставляет (по крайней мере) два варианта для решения проблемы с запросом N + 1. Один устанавливает FetchMode в Subselect, который генерирует выбор с помощью IN-предложения и подзаголовка внутри этого IN-предложения. Другой - указать BatchSize, который генерирует выбор с IN-предложением, содержащим идентификаторы родителей.

Оба работают, но я обнаружил, что опция Subselect часто сталкивается с проблемами производительности из-за того, что запрос для родителей является сложным. С другой стороны, при большом BatchSize (скажем 1000) количество запросов и сложность этих запросов очень малы.

Мой вопрос таков: когда вы используете Hibernate Subselect FetchMode через BatchSize? Subselect, вероятно, имеет смысл, если у вас очень много родительских записей (тысячи), но есть ли другие сценарии, где вы предпочитаете Subselect to BatchSize?

EDIT: Я заметил разницу между ними при работе с нетерпением. Если у вас есть установленная ассоциация xToMany, которая будет загружаться с нетерпением и с помощью подзапроса, она генерирует такой подселек, как если бы она была ленивой. Однако если вы укажете BatchSize, сгенерированный запрос использует внешнее соединение вместо отдельного запроса. Есть ли способ заставить Hibernate использовать отдельный пакетный запрос при загрузке с нетерпением?

4b9b3361

Ответ 1

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

Пакетная загрузка имеет ряд больших преимуществ. Это не всегда самый быстрый, но обычно достаточно быстрый. С другой стороны, он очень стабилен, не имеет побочных эффектов и полностью прозрачен для бизнес-логики. Я никогда не использую значения партии выше 100. Достаточно уменьшить N + 1 до некоторого разумного количества запросов.

Ответ 2

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

В случае стратегии выборки для коллекций подсегмент будет выполняться один раз (потому что размер пакета фактически бесконечен), а при пакетной выборке оператор SQL может выполняться несколько раз.