Hibernate: batch_size? Кэш второго уровня?

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

Используя выборку партии, Hibernate может загружать несколько неинициализированных прокси-серверов, если к одному прокси-серверу обращаются. Пакетная выборка - это оптимизация ленивой стратегии выборки.

hibernate.default_batch_fetch_size:

Используя пакетную выборку, Hibernate может загружать несколько неинициализированных прокси если доступ к одному прокси. Пакетная выборка - это оптимизация ленивая стратегия выбора.

Я также вижу:

hibernate.jdbc.fetch_size:

Значение, отличное от нуля, определяет размер выборки JDBC (вызывает Statement.setFetchSize()).

Хорошо ли Hibernate достаточно умный, чтобы смотреть в кеш второго уровня при выполнении пакетной выборки? i.e Выбираете для первого вызова ассоциации, а затем следующие X-вызовы попадают в кеш? Таким образом, я могу иметь ленивую загрузку, которую я желаю, но также часто попадаю в кеш для более объемных транзакций.

Если все содержимое коллекции уже содержится в кеше, выполнит ли он выборки запросов на доступ к коллекции?

Спасибо.

Ответы

Ответ 1

Сегодня я провел много исследований и смог выработать ответ на мой собственный вопрос. Я просматривал код Hibernate, и поток выглядит следующим образом:

Инициализирована ли коллекция?

  • Нет? Выполняет пакетную выборку (элементы, полученные путем пакетной выборки, помещаются в кеш).
  • Да? Посмотрите в кеш для конкретного элемента, если он не выполняет пакетную выборку.

Итак, если элемент в коллекции, который вы ищете, НАЙДЕН в кеше, тогда пакетная выборка не выполняется. Если элемент НЕ найден в кэше второго уровня, тогда происходит выборка партии, НО она будет делать выборку элементов с сохраненными параметрами независимо от того, находятся ли упакованные элементы в кеше.


----- ПРИМЕР 1 -----

Хорошее:

(Три элемента в коллекции - размер партии 3) Первый вариант:

  • collection.getItem(0) - Нет кеша | пакетная выборка из 3 элементов
  • collection.getItem(1) - Загружен с помощью пакетной выборки
  • collection.getItem(2) - загружен с помощью пакетной выборки

Теперь, где-то еще, позже:

  • collection.getItem(0) - Cache Hit
  • collection.getItem(1) - Cache Hit
  • collection.getItem(2) - Cache Hit

----- ПРИМЕР 2 -----

Плохой:

(Три элемента в коллекции - размер партии 3)

В этом случае элемент с индексом 0 был удален из кеша, потому что, возможно, кеш был заполнен и элемент был удален, или элемент был устаревшим или неактивным.

  • collection.getItem(0) - не в кеше, так что делайте пакет 3 (выберите * где id в (?,?,?))
  • collection.getItem(1) - В кэше уже (заменен пакетной выборкой в ​​любом случае)
  • collection.getItem(2) - В кэше уже (заменен пакетной выборкой в ​​любом случае)

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

http://opensource.atlassian.com/projects/hibernate/browse/HHH-1775

Проголосуйте!