12

To były kilka dni, nad którymi pracuję nad poprawą wydajności NHibernate Insert.Wstawki bezstanowej sesji NHibernate są powolne

czytałem w wielu stanowisk (takich jak this one), które bezpaństwowcem sesja można wstawić jak 1000 ~ 2000 rekordów na sekundę .... jednak najlepszy czas, że może wstawić 1243 rekordów jest więcej niż 9 sekund do mi:

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

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

Klasa:

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; } 
} 

Mapa Klasa:

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(); 
    } 
} 

Czy czegoś brakuje? Każdy pomysł, jak przyspieszyć wstawki?

enter image description here

Generowane zapytań będą takie same, jak poniżej:

enter image description here

Odpowiedz

17

z wyglądu twoich wyników NHProf, używasz tożsamości jako POID. W związku z tym nie można skorzystać z zapisów w pakietach. każda insert/update/delete jest osobnym poleceniem. dlatego trwa to tak długo.

Jeśli zmienisz POID na hilo, guid lub guid.comb i ustawisz wielkość partii na 500 lub 1000, zobaczysz drastyczną poprawę czasów zapisu.

4

Jestem zakładając używasz SQL Server 2008.

kilka rzeczy, które przychodzą na myśl. Czy używasz klucza tożsamości (wybierz SCOPE_IDENTITY() w przykładowym wyniku) jako klucz podstawowy dla swoich podmiotów? Jeśli tak, to wierzę, że NHibernate musi wykonać wywołanie SCOPE_IDENTITY() dla każdego obiektu, zanim obiekt zostanie faktycznie zapisany w bazie danych. Więc jeśli wstawiasz 1000 obiektów, Nhibernate wygeneruje 1000 instrukcji INSERT i 1000 wybierze instrukcje SCOPE_IDENTITY().

Nie jestem w 100% pewny, ale może również przerwać dozowanie. Skoro używasz NHProf, to co mówi? Czy pokazuje, że wszystkie zestawienia są zestawione razem, czy możesz wybrać indywidualną instrukcję INSERT w interfejsie NHProf? Jeśli twoje wkładki nie są wsadowe, najprawdopodobniej zobaczysz alert "Duża liczba indywidualnych zapisów" w NHProf.

Edit:

Jeśli nie można zmienić generację tożsamości następnie można użyć SqlBulkCopy. Użyłem go z NHibernate w migracji danych i działa. Ayende Rahien has sample on his blog, od którego zaczynasz.

+0

tak, inserty są osobnymi zapytaniami. –

+1

W przypadku insertów zbiorczych tam, gdzie liczy się czas, wybrałbym rozwiązanie "SQLBulkCopy". – Rippo

Powiązane problemy