Вставки сессии без сопровождения NHibernate медленны - программирование
Подтвердить что ты не робот

Вставки сессии без сопровождения NHibernate медленны

Через пару дней я работаю над улучшением производительности вставки NHibernate.

Я бы прочитал во многих сообщениях (например, этот), что безстоящий сеанс может вставлять как 1000 ~ 2000 записей в секунду.... Однако лучшее время, в которое он мог вставить 1243 записи, составляет более 9 секунд для меня:

var sessionFactory = new NHibernateConfiguration().CreateSessionFactory();
using (IStatelessSession statelessSession = sessionFactory.OpenStatelessSession())
{
   statelessSession.SetBatchSize(adjustmentValues.Count);

   foreach (var adj in adjustmentValues)
      statelessSession.Insert(adj);
}

Класс:

public partial class AdjustmentValue : PersistentObject, IFinancialValue
{
    public virtual double Amount { get; set; }
    public virtual bool HasManualValue { get; set; }
    public virtual bool HasScaleValue { get; set; }
    public virtual string Formula { get; set; }
    public virtual DateTime IssueDate { get; set; }

    public virtual CompanyTopic CompanyTopic { get; set; }
}

Карта класса:

public class AdjustmentValueMap : ClassMap<AdjustmentValue>
{
    public AdjustmentValueMap()
    {
       Id(P => P.Id);

       Map(p => p.Amount);
       Map(p => p.IssueDate);
       Map(p => p.HasManualValue);
       Map(p => p.HasScaleValue);
       Map(p => p.Formula);

       References(p => p.CompanyTopic)
           .Fetch.Join();
    }
}

Я что-то упустил? Любая идея ускорения вставок?

enter image description here

Сгенерированные запросы будут такими же, как показано ниже:

enter image description here

4b9b3361

Ответ 1

из взглядов ваших результатов NHProf вы используете идентификатор в качестве своего POID. Поэтому вы не можете использовать пакетные записи. каждая вставка/обновление/удаление является отдельной командой. поэтому он занимает так много времени.

если вы измените свой POID на hilo, guid или guid.comb и установите размер партии до 500 или 1000, вы увидите резкое улучшение времени записи.

Ответ 2

Я предполагаю, что вы используете SQL Server 2008.

Немногие вещи, которые приходят на ум. Используете ли вы ключ идентификации (выберите SCOPE_IDENTITY() в своем примере вывода) в качестве первичного ключа для своих объектов? Если да, то я верю, что NHibernate должен выполнить вызов SCOPE_IDENTITY() для каждого объекта до того, как объект фактически будет сохранен в базе данных. Поэтому, если вы вставляете 1000 объектов, Nhibernate будет генерировать 1000 инструкций INSERT и 1000 select SCOPE_IDENTITY() операторов.

Я не уверен на 100%, но это может также сломать пакет. Так как вы используете NHProf, то что он говорит? Означает ли это, что все утверждения объединены вместе или вы можете выбрать индивидуальный оператор INSERT в пользовательском интерфейсе NHProf? Если ваши вставки не упакованы, вы, скорее всего, увидите сообщение "Большое количество отдельных записей" в NHProf.

Edit:

Если вы не можете изменить свое удостоверение личности, вы можете использовать SqlBulkCopy. Я использовал его с NHibernate в миграции данных, и он работает. Айенде Рахиен имеет образец в своем блоге, в котором вы начали.