Очень низкая производительность из-за Nhibernate и шаблона Unitwork

#c# #asp.net-mvc #nhibernate #fluent-nhibernate

#c# #asp.net-mvc #nhibernate #свободно владеет nhibernate

Вопрос:

У меня есть один сложный объект, подобный этому

  A
|
|
|                 |->C(As child)---->it has 4 hastomany properties(each B has 10000 C child)
B(has many child)->
                  |->D(As child)---->it has 4 hastomany properties(each B has 1o000 D child)
                  |->B Has many prop also
|
|
|A has many prop also
  

Я страдаю от производительности. В совокупности при получении этой записи я могу ожидать, что Nh выполнит 1000-2000 запросов. Но наихудшая производительность по NH 10-20 Тыс. запросов, которые он запускает.

Здесь я выполняю чтение и запись только для объекта A. Я не вставляю по отдельности ни одного дочернего элемента A, ни retrival. Я запускаю команду Get для объекта A и записываю обратно только объект A.

Каскадирование также заботится о вставке дочернего элемента A-> его дочернего элемента.

здесь я очень сильно страдаю от производительности, я не знаю, что здесь делать.

Ответ №1:

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

 HasMany(x => x.OrderLines)
            .FetchType.Select();
  

или

 HasMany(x => x.OrderLines)
            .FetchType.Join();
  

Это означает, что при загрузке родительского объекта также будут загружены все эти коллекции, что может привести к печально известной проблеме «выбрать n 1».

Ниже приведена документация nhibernate:

(3) выборка (необязательно, по умолчанию используется join): включает извлечение с помощью внешнего соединения или последовательного выбора для этой ассоциации. Это особый случай; для полной быстрой выборки (за один ВЫБОР) объекта и его отношений «многие ко многим» с другими объектами вам следует включить выборку объединения не только из самой коллекции, но также с этим атрибутом во вложенном элементе.

Если вы не можете изменить свои сопоставления, я бы рекомендовал создавать запросы заранее, чтобы получить все дочерние коллекции. Таким образом, вы выполняете только 1 запрос на объект, а не 1000 запросов, которые nhibernate выполняет в настоящее время с помощью отложенной загрузки.