Первая и наиболее существенная проблема с производительностью, с которой вы можете столкнуться с NHibernate, - это если вы создаете новую фабрику сеансов для каждого сеанса, который вы создаете. Для каждого выполнения приложения должен быть создан только один экземпляр фабрики сеансов, и все фабрики должны быть созданы этой фабрикой.
Вдоль этих строк вы должны продолжать использовать тот же сеанс, если это имеет смысл. Это зависит от приложения, но для большинства веб-приложений рекомендуется один сеанс на запрос. Если вы часто выбрасываете сеанс, вы не получаете преимуществ от его кэша. Интеллектуальное использование кеша сеанса может изменить процедуру с линейным (или хуже) числом запросов на постоянное число без особой работы.
Не менее важно, что вы хотите убедиться, что лениво загружаете ссылки на свои объекты. Если нет, можно загрузить целые графы объектов даже для самых простых запросов. Есть только определенные причины не делать этого, но всегда лучше начинать с отложенной загрузки и переключаться обратно по мере необходимости.
Это приводит нас к страстному желанию, противоположному ленивой загрузке. Обходя иерархии объектов или просматривая коллекции, можно легко потерять счет того, сколько запросов вы делаете, и в результате вы получите экспоненциальное количество запросов. Стремительное извлечение может быть сделано для каждого запроса с помощью FETCH JOIN. В редких случаях, например, при наличии определенной пары таблиц, к которым вы всегда получаете соединение, рассмотрите возможность отключения отложенной загрузки для этих отношений.
Как всегда, SQL Profiler - отличный способ найти запросы, которые выполняются медленно или выполняются неоднократно. На моей последней работе у нас была функция разработки, которая также подсчитывала количество запросов на страницу. Большое количество запросов для подпрограммы является наиболее очевидным показателем того, что ваша подпрограмма плохо работает с NHibernate. Если количество запросов на подпрограмму или запрос выглядит хорошо, вы, вероятно, приступили к настройке базы данных; убедитесь, что у вас достаточно памяти для хранения планов выполнения и данных в кеше, правильной индексации данных и т. д.
Одна хитрая маленькая проблема, с которой мы столкнулись, была с SetParameterList (). Функция позволяет легко передавать список параметров в запрос. NHibernate реализовал это, создав один параметр для каждого переданного элемента. Это приводит к разному плану запросов для каждого количества параметров. Наши планы выполнения почти всегда выходили из кеша. Кроме того, многочисленные параметры могут значительно замедлить запрос. Мы сделали собственный хакер NHibernate для отправки элементов в виде списка с разделителями в виде одного параметра. Список был разделен в SQL Server функцией табличных значений, которую наш хак автоматически вставил в предложение IN запроса. Могут быть и другие наземные мины в зависимости от вашего применения. SQL Profiler - лучший способ их найти.