Hibernate: batch_size? Кэш второго уровня? - PullRequest
13 голосов
/ 25 августа 2009

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

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

hibernate.default_batch_fetch_size

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

Я также вижу:

hibernate.jdbc.fetch_size

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

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

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

Спасибо.

1 Ответ

6 голосов
/ 26 августа 2009

Я провел много исследований сегодня и смог найти ответ на свой вопрос. Я просматривал код Hibernate и поток выглядит так:

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

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

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


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

Добро:

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

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

Теперь, где-то еще, позже во времени:

  • collection.getItem (0) - попадание в кэш
  • collection.getItem (1) - попадание в кэш
  • collection.getItem (2) - попадание в кэш

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

Плохое:

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

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

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

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

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

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

...