Ответ 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
Проголосуйте!