2009-08-25 3 views
13

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

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

hibernate.default_batch_fetch_size:

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

Я также вижу:

hibernate.jdbc.fetch_size:

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

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

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

Спасибо.

+0

Теперь это то, что я хотел бы знать и ответ. – Zoidberg

+1

Подпишите мой вопрос :-) – davidemm

ответ

6

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

Является ли коллекция инициализированной?

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

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


----- Пример 1 -----

Хорошо:

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

  • collection.getItem (0) - Нет кеша | batch-fetch 3 items
  • коллекция.GetItem (1) - Загруженные в партии по-выборки
  • collection.getItem (2) - Загруженный в партии по-выборка

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

  • коллекции. GetItem (0) - Cache Hit
  • collection.getItem (1) - Cache Hit
  • collection.getItem (2) - Cache Hit

----- ----- Пример 2

Плохое:

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

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

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

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

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

Голосуйте его!

Смежные вопросы