Обычная ловушка в спящем режиме - PullRequest
9 голосов
/ 04 мая 2010

Мы только что закончили профилировать нашу заявку. (она начинает медленно). проблема, кажется, "в спящем режиме".

Это устаревшее отображение. Кто работает, и делает свою работу. С реляционной шемой тоже все в порядке.

Но некоторые запросы медленны, как ад.

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

Пример: Стремление вместо Ленивого может резко изменить время отклика ...


Редактировать: Как обычно, читать руководство часто является хорошей идеей. Целая глава охватывает эту тему здесь:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html

Ответы [ 7 ]

17 голосов
/ 04 мая 2010

Одной из наиболее распространенных ошибок является печально известная n + 1 выбор проблемы . По умолчанию Hibernate не загружает данные, которые вы не запрашивали. Это уменьшает потребление памяти, но подвергает вас проблеме выбора n + 1, которой можно избежать, переключившись на правильную стратегию выборки, чтобы извлечь все данные, необходимые для загрузки объектов в их надлежащим образом инициализированном состоянии.

Но также не извлекайте слишком много информации, иначе вы столкнетесь с противоположной проблемой - декартовой проблемой продукта : вместо выполнения многих операторов SQL вы можете в конечном итоге создать операторы, которые получают слишком много данные.

В этом весь смысл настройки: найти середину между недостаточным и слишком большим количеством данных для каждого варианта использования вашего приложения (или, по крайней мере, для варианта, который требуется настроить).

Мои рекомендации:

  • сначала активировать ведение журнала SQL на уровне Hibernate
  • запустить критические случаи использования (20% использовали 80% времени) или даже все из них, если у вас есть такая роскошь
  • выявить подозрительные запросы и оптимизировать план извлечения, проверить, правильно ли используются индексы и т. Д.
  • привлекать вашего DBA
2 голосов
/ 19 августа 2014

Наиболее распространенные ошибки - выбор N + 1, который скрыт за кулисами. Обычно они не обнаруживаются до производства, и обычные профилировщики не очень хорошо их обнаруживают.

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

http://zeroturnaround.com/blog/hibernate-orm-with-xrebel-revealing-multi-query-issues-with-an-interactive-profiler/

XRebel showing SQL queries

2 голосов
/ 21 февраля 2011

Я хотел бы одобрить все, что сказал Паскаль, и просто упомянуть дополнительно, что одним из решений «извлечения слишком большого количества данных» является использование проекций Hibernate и выборка данных в плоский DTO, который состоит только из колонны действительно нужны. Это особый вариант, когда вы не планируете обновлять данные в этом сеансе Hibernate, следовательно, вам не понадобятся сопоставленные объекты. Взято из этой статьи , в которой содержатся дополнительные советы по производительности Hibernate.

1 голос
/ 06 августа 2015

Как уже упоминалось, проблема N + 1 является распространенной проблемой в приложениях JPA. В настоящее время я работаю над инструментом для раннего обнаружения этих проблем в ваших модульных тестах и ​​в ваших тестовых средах. Он называется JDBC Sniffer , с открытым исходным кодом и совершенно бесплатно

Позволяет отслеживать количество запросов, выполненных в ваших тестовых средах прямо в браузере: enter image description here

Кроме того, он предоставляет расширенные возможности для популярных платформ модульных тестов для решения проблемы N + 1, пока вы все еще разрабатываете код с использованием аннотаций:

import com.github.bedrin.jdbc.sniffer.BaseTest;
import com.github.bedrin.jdbc.sniffer.Threads;
import com.github.bedrin.jdbc.sniffer.Expectation;
import com.github.bedrin.jdbc.sniffer.Expectations;
import com.github.bedrin.jdbc.sniffer.junit.QueryCounter;
import org.junit.Rule;
import org.junit.Test;

public class QueryCounterTest extends BaseTest {

    // Integrate JDBC Sniffer to your test using @Rule annotation and a QueryCounter field
    @Rule
    public final QueryCounter queryCounter = new QueryCounter();

    @Test
    @Expectations({
            @Expectation(atMost = 1, threads = Threads.CURRENT),
            @Expectation(atMost = 1, threads = Threads.OTHERS),
    })
    public void testExpectations() {
        executeStatement();
        executeStatementInOtherThread();
    }

}
1 голос
/ 04 мая 2010

Одна вещь, которая произошла в моей компании, приходит на ум. Вы могли видеть, загружает ли объект также загрузку некоторого объекта serialized, который будет десериализоваться каждый раз, когда объект загружается. Кроме того, при фиксации транзакции Hibernate может сделать flush() для вас (настраивается). Если он сбрасывается, чтобы сохранить постоянство, он выполнит сравнение прав доступа и базы данных. В этом случае выполняется сравнение объекта serialized, что занимает много времени.

Еще одна вещь, которую вы можете сделать, это проверить, нет ли у вас ненужного каскадирования персистентности, то есть @Cascade({CascadeType.PERSIST, CascadeType.SAVE_UPDATE}) аннотации к столбцам.

Еще одна вещь, которую вы можете сделать, которая не специально связана с hibernate, заключается в том, что вы создаете view s для выполнения одного запроса, вместо того, чтобы выполнять множество запросов к разным таблицам. Это имело огромное значение для нас в определенной функции.

0 голосов
/ 16 сентября 2013

Отображение отношений m: n и n: 1 является корнем частых проблем с производительностью в Hibernate.

Кэширование Hibernate не может помочь, если вы используете HQL, поскольку Hibernate не может преобразовывать запросы в вызовы кеша, поэтому он не может использовать кеш с HQL (по крайней мере, когда я читал его код).

Если вы хотите простой, быстрый и легкий подход, я могу порекомендовать fjorm

Dislaimer: я основатель проекта fjorm

0 голосов
/ 04 мая 2010

Как уже упоминали ребята, производительность Hibernate зависит от правильных настроек. Однажды мне удалось повысить скорость обновления кэша некоторых учетных данных в 10 раз (с 2 до 200 мс), переключившись на сеанс без сохранения состояния (этот конкретный код не зависел от какого-либо типа отложенной выборки, поэтому я мог безопасно делать то, что делал) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...