Gymterview
senior

Что такое Query Cache?

Query Cache — кэш результатов JPQL/HQL-запросов. Хранит не данные сущностей, а список ID, возвращённых запросом с определёнными параметрами.

Как работает

Пример
Ключ кэша: запрос + параметры
Значение: список ID сущностей

При чтении: Query Cache → получить ID → L2 Cache → получить данные по ID → (если нет в L2 → БД)

Настройка

Пример
spring.jpa.properties.hibernate.cache.use_query_cache=true
Пример
// JPQL с кэшированием
List<User> users = entityManager.createQuery(
        "SELECT u FROM User u WHERE u.status = :status", User.class)
    .setParameter("status", UserStatus.ACTIVE)
    .setHint("org.hibernate.cacheable", true)
    .getResultList();

// Spring Data JPA
@QueryHints(@QueryHint(name = "org.hibernate.cacheable", value = "true"))
@Query("SELECT u FROM User u WHERE u.status = :status")
List<User> findByStatus(@Param("status") UserStatus status);

Важное

  • Query Cache хранит список ID, а не данные — работает в связке с L2 Cache
  • Query Cache инвалидируется при любом изменении таблицы, участвующей в запросе
  • Эффективен только для запросов, которые выполняются часто с одинаковыми параметрами
  • Без L2 Cache — Query Cache бесполезен (ID есть, но данные придётся загружать из БД)

Частые ошибки

  • Включать Query Cache без L2 Cache — получив список ID из Query Cache, Hibernate пойдёт за каждой сущностью в БД (хуже, чем без кэша)
  • Кэшировать запросы к часто обновляемым таблицам — любой UPDATE/INSERT/DELETE инвалидирует весь Query Cache для этой таблицы
  • Кэшировать все запросы подряд — Query Cache полезен только для стабильных данных с повторяющимися параметрами

Как используется в 2026

  • Query Cache — нишевый инструмент, используется реже L2 Cache
  • Для большинства задач кэширования на уровне запросов — Spring Cache + Redis
  • Query Cache оправдан для тяжёлых аналитических запросов к неизменяемым данным

На собеседовании: покажите, что понимаете связку Query Cache + L2 Cache. Без L2 Cache включать Query Cache бессмысленно и даже вредно. Подчеркните, что Query Cache инвалидируется при любом изменении таблицы — это делает его бесполезным для часто обновляемых данных.