Вставки сессии без сопровождения 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]()
Ответы
Ответ 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 в миграции данных, и он работает. Айенде Рахиен имеет образец в своем блоге, в котором вы начали.