Стратегия выборки из гибернации - когда использовать “присоединиться", а когда “выбрать”?

StackOverflow https://stackoverflow.com/questions/617145

  •  03-07-2019
  •  | 
  •  

Вопрос

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

fetch="join|select"

при этом "выбрать" является значением по умолчанию.

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

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

Спасибо.

Это было полезно?

Решение

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

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

Другие советы

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)

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

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

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

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

источник :Стратегии загрузки в спящий режим

JOIN обычно предпочтительнее из соображений производительности.

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

Люди всегда говорят о снижении производительности, используя выборка = ПРИСОЕДИНЯЙТЕСЬ.Но, как я считаю, нам важно понимать, сколько родительских/дочерних записей мы извлекаем:

Если вы хотите получить только одну родительскую запись и ожидаете, что у нее не так много дочерних записей, я бы предложил вам использовать выборка = ВЫБРАТЬ.

Если вы хотите получить все родительские записи, включая дочерние, лучше использовать выборка = ПРИСОЕДИНЯЙТЕСЬ

Просто хочу добавить примечание, что если записи лениво извлекают дочерние элементы(ленивый = правда), тогда не будет смысла использовать выборка = ПРИСОЕДИНЯЙТЕСЬ поскольку все родительские и дочерние записи загружаются за один раз.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top