Вы должны узнать о Hibernate кеш запросов .Проще говоря: он работает поверх кэша второго уровня (L2
) и хранит результаты запросов. Но хранит только идентификаторы записей, которые должны быть возвращены запросом, а не весь список.Это означает, что вам нужно, чтобы L2 работал и был точно настроен.
В вашем сценарии предположим, что у вас есть 1M записей в таблице T
и запрос, который возвращает 1K в среднем.При первом запуске этого запроса он пропустит кэш запроса и:
- запустит SQL
- извлечет записи из 1 КБ
- поместит их все в L2
- поместите 1K идентификаторы в кэш запросов
При следующем выполнении запроса он попадет в кэш запросов и выполнит поиск всех результатов из L2.Интересная часть возникает, когда вы модифицируете таблицу T
.Hibernate выяснит, что результаты в кеше запросов могут быть устаревшими, и это сделает недействительным весь кеш, но не L2.Он будет в основном повторять пункты 1-4, но обновлять только кеш запросов (большинство объектов из таблицы T
уже находятся в L2).
В некоторых сценариях он работает отлично, в других он вызывает проблемы N + 1 внепредсказуемые моменты.Это всего лишь верхушка айсберга, вы должны быть очень осторожны, так как этот механизм очень хрупок и требует глубокого понимания.