Ответ 1
- Не используйте соединения, если это действительно необходимо. Они не позволят вам использовать ни ленивую загрузку, ни использование кеша второго уровня для ассоциаций.
- Используйте lazy = "extra" для больших коллекций, он не будет извлекать все элементы до тех пор, пока вы его не спросите, вы также можете использовать метод size(), не получая элементы из DB
-
Использовать метод load(), если это возможно, поскольку он не выдает запрос выбора до его появления. Например. если у вас есть книга и автор, и вы хотите связать их вместе, это не будет выдавать никаких отборов, только одна вставка:
Book b = (Book) session.load(Book.class, bookId); Author a = (Author) session.load(Author.class, authorId); b.setAuthor(a); session.save(b);
-
Используйте именованные запросы (в ваших файлах hbm или в @NamedQuery), чтобы они не анализировались во время каждого запроса. Не используйте API критериев до тех пор, пока он не понадобится (в этом случае невозможно использовать кеш PreparedStatement)
- Используйте OSIV в своем веб-приложении, так как он будет загружать данные только тогда, когда/если это необходимо.
- Используйте режимы только для чтения только для выборок:
session.setReadOnly(object, true)
. Это приведет к тому, что Hibernate не будет сохранять исходный снимок выбранного объекта в постоянном контексте для последующих грязных проверок. - Пользовательский кеш второго уровня и кэш запросов для данных, предназначенных только для чтения и чтения.
- Используйте FlushMode.COMMIT вместо AUTO, чтобы Hibernate не выдавал выбор перед обновлениями, но будьте готовы к тому, что это может привести к записи устаревших данных (хотя Optimistic Locking может помочь вам).
- Посмотрите на пакетную выборку (размер партии), чтобы выбрать несколько объектов/коллекций за один раз, вместо того, чтобы выпускать отдельные запросы для каждого из них.
- Выполняйте запросы типа "выберите новый Entity (id, someField) из Entity", чтобы получить только необходимые поля. Посмотрите на трансформаторы результатов.
- При необходимости используйте пакетные операции (например, удаление)
- Если вы используете собственные запросы, укажите явно, какие области кэша должны быть недействительными (по умолчанию - все).
- Взгляните на материализованный путь и вложенные множества для древовидных структур.
- Установите
c3p0.max_statements
, чтобы включить кеш PreparedStatment в пул и включить кеш оператора в вашей БД, если он по умолчанию отключен. - Используйте StatelessSession, если это возможно, оно преодолевает грязные проверки, каскадирование, перехватчики и т.д.
- Не используйте разбивку на страницы (
setMaxResults()
,setFirstResult()
) вместе с запросами, которые содержат объединения к коллекциям, это приведет к тому, что все записи будут извлечены из базы данных, а разбиение на страницы произойдет в памяти с помощью Hibernate. Если вам нужна разбивка на страницы, в идеале вы не должны использовать объединения. Если вы не можете избежать этого, снова - используйте пакетную выборку.
На самом деле есть много трюков, но я не могу вспомнить больше на данный момент.