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

Стратегия выбора Hibernate - когда использовать "join" и когда использовать "select"?

Большинство ассоциаций Hibernate поддерживают параметр "выборки":

fetch="join|select"

с "select" значением по умолчанию.

Как решить, какой из них использовать для какой ассоциации?

Я попробовал изменить все из приложения "select" to "join" - количество сгенерированных запросов уменьшилось, вероятно, в 10 раз, но производительность осталась одинаковой (даже немного хуже).

Спасибо.

4b9b3361

Ответ 1

Соединение должно решить проблему n + 1. Если у вас 10 родителей, у каждого из которых 10 детей, для соединения потребуется один запрос, а для выбора потребуется 11 (один для родителей и один для детей каждого родителя). Это может быть неважно, если база данных находится на том же сервере, что и приложение, или если сеть работает очень быстро, но если в каждом вызове базы данных есть латентность, она может складываться. Метод соединения немного менее эффективен при первоначальном запросе, потому что вы дублируете родительские столбцы в каждой строке, но вы делаете только одно туда-обратно в базу данных.

В общем, если я знаю, что мне понадобятся дети всех родителей, я иду с ними. Если мне понадобятся только дети нескольких родителей, я использую select.

Ответ 2

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

Выбрать:

SELECT * FROM parent WHERE id=(whatever)
SELECT * FROM child WHERE id=(parent.child.id)

Регистрация:

SELECT *
FROM parent
LEFT OUTER JOIN child ON parent.child.id=child.id
WHERE parent.id=(whatever)

Что касается того, когда использовать один над другим... Не совсем уверен. Вероятно, это зависит от системы базы данных. Если кто-то всегда был лучше другого, я сомневаюсь, что они потрудились бы дать вам возможность! Если вы видите подобную производительность для каждого, я бы не стал беспокоиться об этом.

Ответ 3

выборка = "присоединиться к" Если вы делаете fetchching = "join", он будет извлекать всю информацию в одном выражении select.

выборка = "выберите" если вы хотите использовать второй оператор select для извлечения связанной коллекции, то в этом случае вы будете использовать fetch = "select".

источник: Стратегии по слиянию с гибернацией

Ответ 4

Люди всегда говорят об эффективности, используя fetch = JOIN. Но, как я считаю, для нас важно понять количество родительских/дочерних записей, которые мы извлекаем:

Если вы хотите получить только одну родительскую запись и ожидаете, что у нее мало детей, я предлагаю вам использовать fetch = SELECT.

Если вы хотите получить все родительские записи, включая его дочерние элементы, тогда лучше было бы выбрать fetch = JOIN

Просто добавьте примечание о том, что если записи лениво извлекают детей (lazy = true), тогда не было бы смысла использовать fetch = JOIN, поскольку все родительские и дочерние записи загружаются одним выстрелом.

Ответ 5

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

Ответ 6

JOIN предпочтительнее, как правило, по соображениям производительности.

Единственной причиной использования SELECT является то, что вы выполняете поисковые запросы (устанавливаете смещение и лимит), которые имеют отношение "многие ко многим". Если вы используете JOIN, корневой объект будет появляться несколько раз, если он содержит несколько детей "много ко многим", и эти "копии" учитывают ваш лимит (даже если Hibernate обрушивает их после факта, используя DISTINCT_ROOT_ENTITY).