@BatchSize умное или глупое использование?
Сначала я объясню, как я понял и использую @BatchSize
: @BatchSize
для загрузки отношений объектов в пакетном режиме, делая меньше запросов SQL к базе данных. Это особенно полезно для LAZY @OneToMany
отношений.
Однако это даже полезно в отношении LAZY @OneToOne
и @ManyToOne
: если вы загружаете список сущностей из базы данных и запрашиваете загрузку lazyed объекта @*ToOne
, он будет загружать объекты @*ToOne
, даже если я просто использую тест, который загружает отношение 1-го объекта списка.
Обратите внимание, если некоторые хотят проверить: это только показывает, если сущности еще не загружены: например, если у вас есть список пользователей с менеджером и список всех пользователей, когда вы получите доступ к менеджеру, запрос не будет запущен, так как он уже загружен.
- Сохранять общий запрос в виде столбца?
- Как выполнять операции обновления столбцов типа JSONB в Postgres 9.4
- Временной интервал Postgresql SQL GROUP BY с произвольной точностью (до миллисекунды)
- Не удается найти заголовок libpq-fe.h при попытке установить pg gem
- Адаптер Postgresql (pg): не удалось подключиться к серверу
Единственный недостаток, который я вижу в этом методе, заключается в том, что вы загружаете список элементов из базы данных, но используете только его часть. Это операция постфильтрации.
Итак, давайте перейдем к главному.
Предположим, что я делаю все возможное, чтобы никогда не выполнять пост-фильтрующие операции, даже если это заставляет меня выполнять собственные SQL-запросы или использовать объекты DTO для запроса критериев выбора и т. Д.
- Правильно ли я считаю, что я могу просто
@BatchSize
каждые lazyed отношения после того, как тщательно подумали об использовании нетерпеливой загрузки / присоединения и, наконец, выбрать ленивое отношение? - У меня есть интерес к поиску адекватного значения для
@BatchSize
или я могу подумать «чем больше, тем лучше»? Это означает, что «существует ли какой-либо предел числа в операторе« IN »SQL, который может сделать мой запрос достаточно медленным, чтобы он не стоил больше? Я использую Postgres, но если у вас есть ответы на другие вопросы, которые мне тоже интересны, я тоже заинтересован. - Необязательный вопрос: кажется, что использование
@BatchSize
в classе не дает много результатов. Мне все равно приходится комментировать все ленивые отношения, я что-то пропустил или это бесполезно?
EDIT: Точка моего 3 заключается в том, что я получаю другое поведение.
Скажем, я загружаю список сущностей classа «A», у которого отношение LAZY OneToMany к B. Теперь я хочу напечатать все createDate из B. Так что я делаю classический цикл 2 для цикла.
Я теперь аннотировал B с BatchSize:
- @OneToMany не аннотируется с BatchSize: каждый набор B загружается на каждой итерации независимо без пакетной обработки. Таким образом, моя аннотация в classе B, кажется, полностью игнорируется. Даже если я установил значение «два», и у меня есть 6 записей в одном наборе, у меня есть один запрос для этого набора.
- @OneToMany аннотируется: у меня есть конкретный запрос загружаемых партий. Если я исправлю размер партии до двух, и у меня будет всего 10 B accros, я просто получаю 5 запросов: независимо от числа A i. Если я установил его в 100: у меня есть 1 запрос для объектов B.
PS: Я не рассматриваю какой-либо связанный запрос с B, который мог бы запустить загрузку полей B с выбором / подбором выборки.
EDIT 2: я только что нашел этот пост. Почему бы мне не использовать @BatchSize для каждого ленивого загруженного отношения? Хотя я googled и поиск на SO, прежде чем мой вопрос, думаю, я не использовал правильные слова …
Однако я добавляю что-то другое, что может привести к другому ответу: когда мне интересно об использовании BatchSize для каждого отношения, он выбирает, хочу ли я желать загрузки, с помощью join / select fetch или если мне нужна ленивая загрузка.
- Postgresql скрипт для второго экземпляра?
- Как подключиться к Postgres через Node.js
- Как регистрировать запросы PostgreSQL?
- Перечисления Java, enums JPA и Postgres - Как мне заставить их работать вместе?
- Названия часовых поясов с одинаковыми свойствами дают разные результаты при применении к метке времени
- Общее решение Ruby для SQLite3 «LIKE» или PostgreSQL «ИЛИКЕ»?
- Pyodbc - «Имя источника данных не найдено, а драйвер по умолчанию не указан»
- Справочный псевдоним в предложении WHERE
- Да,
@BatchSize
предназначен для использования с ленивыми ассоциациями. - В любом случае Hibernate будет выполнять несколько операторов в большинстве ситуаций, даже если количество неинициализированных прокси / коллекций меньше заданного размера партии. См. Этот ответ для получения более подробной информации. Кроме того, более легкие запросы по сравнению с менее крупными могут положительно влиять на общую пропускную способность системы.
-
@BatchSize
на уровне classа означает, что указанный размер партии для объекта будет применяться для всех@*ToOne
ленивых ассоциаций с этим объектом. См. Пример с объектомPerson
в документации .
Связанный вопрос / ответы, которые вы предоставили, больше обеспокоены необходимостью оптимизации и ленивой загрузки в целом. Они также применимы и здесь, но они не связаны только с пакетной загрузкой, что является одним из возможных подходов.
Еще одна важная вещь связана с энергичной загрузкой, о которой упоминается в связанных ответах, и которая предполагает, что если свойство всегда используется, вы можете получить лучшую производительность, используя активную загрузку. Это, в общем, неверно для коллекций и во многих ситуациях для одних ассоциаций.
Например, предположим, что у вас есть следующий объект, для которого bs
и cs
всегда используются, когда используется A
public class A { @OneToMany private Collection bs; @OneToMany private Collection cs; }
С нетерпением загружая bs
и cs
очевидно, страдает от N + 1, выбирает проблему, если вы не присоединяете их в одном запросе. Но если вы присоединитесь к ним в одном запросе, например, например:
select a from A left join fetch a.bs left join fetch a.cs
то вы создаете полное декартово произведение между значениями bs
и cs
и count(a.bs) x count(a.cs)
в наборе результатов для каждого a
которые читаются один за другим и собираются в сущности A
и их коллекции bs
и cs
.
Пакетная выборка была бы очень оптимальной в этой ситуации, потому что сначала вы должны прочитать A
s, затем bs
а затем cs
, что приведет к большему количеству запросов, но с гораздо меньшим количеством данных, которые передаются из базы данных. Кроме того, отдельные запросы намного проще, чем большие, с объединениями, и проще выполнять и оптимизировать базу данных.