Hibernate JPA генерирует запрос выбора каждый раз, когда findOne (идентификатор строки) вызывается с тем же значением параметра - PullRequest
0 голосов
/ 18 мая 2018

Hibernate findOne (идентификатор строки) в нашем случае занимает много времени (более 300 мс).Это также не соответствует.Для некоторого запроса он возвращает результат менее чем за 100 мс.

Поэтому мы хотим улучшить производительность findOne, где это не должно занимать более 100 мс времени.Поскольку в таблице более 100 тыс. Записей, у нас есть индексация для сущностей, участвующих в запросе выбора.

Мы вызываем этот метод findOne для каждого запроса клиента.Изменится только значение в предложении where, а не столбцы или сущности, участвующие в этом.

Поэтому в принципе было бы здорово, если бы Hibernate мог создать / сгенерировать запрос select один раз и повторно использовать его для всехfindOne вызывает хранилище.

Может ли кто-нибудь помочь мне с этим?

1 Ответ

0 голосов
/ 18 мая 2018

Здесь можно рассмотреть несколько оптимизаций.

  1. HTTP-сессия
  2. Кэш второго уровня
  3. Использование @NamedQuery, где это возможно
  4. Не используйте первичные ключи на основе строк.

Кэш HTTP-сессии

Вы всегда можете сохранить объект, который вы выбираете с помощью метода #findOne, в сеансе HTTP, когда клиентпроверяет подлинность и значение не существует.Это исключит запросы на все последующие аутентифицированные запросы.Единственное беспокойство, которое вы должны предпринять, - если рассматриваемый объект был изменен текущим пользователем, вы захотите заменить значение в сеансе обновленной копией.

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

Кэш второго уровня

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

Хорошая вещь в 2LC в том, что вы можетенастройте для каждого запроса, если он будет кэшироваться, и вы также можете настроить различные таймауты и другие параметры конфигурации для каждого типа объекта.

@ NamedQuery

Иногда выполнение сложных запросов выполняется за счетJPQL / HQL повторяется.Если вы обнаружите, что это является проблемой, вы можете посмотреть, можно ли вместо этого переместить запрос в статический @NamedQuery.

Преимущество @NamedQuery заключается в том, что синтаксический анализ, проверка и построение базового дерева синтаксического анализа выполняются один раз во время повышения уровня приложения.Это означает, что во время выполнения Hibernate просто выбирает это определение, получает предварительно сгенерированный SQL, применяет привязки параметров и передает их в базу данных.За исключением проверки типа параметра, накладные расходы очень минимальны.

Нет ключей на основе строк

В зависимости от вашей платформы базы данных первичные ключи на основе строк могут работать намного хуже, чем их числовые счетчики, особенноесли ваш запрос участвует в объединениях.Если ваше строковое поле сконфигурировано для поддержки юникода (например, столбцы NVARCHAR или NCHAR), вы усугубляете проблему.

Использование String для @NaturalId прекрасно, потому что вы обычно просто применяетегде предикат против того поля, в котором вы можете применять различные индексы в соответствии с вашими запросами.

Но я бы посоветовал, если в вашем запросе используется первичный ключ на основе строк, переместите его на @NaturalId и используйте суррогатный числовой ключ для первичного ключа.Вы заметите, что ваши объединения таблиц значительно улучшат производительность, так как сравнение и поиск хеша между ними намного быстрее.

...