NHibernate select растет экспоненциально медленно - PullRequest
6 голосов
/ 28 января 2010

Моя проблема в том, что NHibernate становится экспоненциально медленным при извлечении записей из базы данных. У меня был запрос на получение всех данных из очень большой базы данных для использования в отчете.

Я подумал, ну, так как я не могу получить все записи за один снимок, потому что набор записей настолько велик, я подумал, попытайтесь разбить его. В основном я перебираю диапазоны индекса, т.е. записывает id от x до y, затем от y + 1 до z и т. д.

Каждый набор результатов составляет около 10 мг. Первые 20 или около того тянет длится менее минуты, затем на следующем тянется 10 минут, затем 30 минут и 1 час. Я остановил программу там, не хотел ждать, пока придет следующий рывок. Я снова запустил программу, начиная с индекса, на котором остановился, опять же, первые 20 или около того пулеров очень быстрые, а затем по какой-то странной причине происходит значительное замедление.

Любая помощь будет принята с благодарностью.

Ответы [ 4 ]

8 голосов
/ 28 января 2010

NHibernate делает много работы для вас, и это может замедлить его.Он сохраняет объекты, которые вы извлекли в сеансе, который в основном является кэшем первого уровня.Когда вы запускаете запросы, он проверяет этот набор объектов, чтобы увидеть, нужно ли их сбрасывать обратно в базу данных (возможно, вы изменили их, чтобы они теперь квалифицировались как результат запроса!).Таким образом, одна серьезная возможность состоит в том, что ваш запрос тайно проходит через огромное количество объектов, пытаясь выяснить, что он должен записать в базу данных, прежде чем он когда-либо отправит ваш запрос в базу данных.

В этом случае вы можете попробовать использовать метод period.Clear () или session.Evict (объект), который удаляет объекты из кэша, чтобы NH не пытался привести базу данных в соответствие с ними.,Вы всегда можете прикрепить объекты позже, если вы хотите, чтобы NH «обратил на них внимание».

Редактировать : или использовать сеанс без сохранения состояния.Вот пример .

3 голосов
/ 28 января 2010

В качестве опции вы можете попробовать использовать StatelessSession.Он не будет отслеживать все вытащенные объекты и не замедлит работу вашего приложения

1 голос
/ 28 января 2010

Очень вероятная причина - отсутствие индексов. Предложите разместить в этих таблицах запрос, определение таблицы и текущие индексы.

Для создания отчетов вам может потребоваться создать хранимую процедуру (возможно, даже индексированное представление, если задействована большая агрегация) и обернуть ее с помощью NHibernate.

Я бы также запустил SQL Profiler, чтобы увидеть, какие запросы выполняются.

Интерес ?: Оптимизация производительности в NHibernate

1 голос
/ 28 января 2010

Есть несколько способов повысить производительность NHiberante

  • Кэш второго уровня
  • Стремится к загрузке, чтобы предотвратить выбор n + 1
  • Несколько способов выжать производительность из сопоставления
  • Изменение индексов базы данных

Когда это занимает столько времени, сколько вы описываете, я не думаю, что описанные выше вещи будут работать для вас достаточно хорошо.

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

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