Les insertions de session sans état de NHibernate sont lentes
Ça fait quelques jours que je suis en train de travailler sur l'amélioration de NHibernate la performance de l'Insert.
J'avais lu dans de nombreux postes (comme cette une) que stateless session pouvez insérer comme 1000~2000 enregistrements par seconde.... Mais le meilleur moment qu'il pouvait insérer 1243 dossiers de plus de 9 secondes pour moi :
var sessionFactory = new NHibernateConfiguration().CreateSessionFactory();
using (IStatelessSession statelessSession = sessionFactory.OpenStatelessSession())
{
statelessSession.SetBatchSize(adjustmentValues.Count);
foreach (var adj in adjustmentValues)
statelessSession.Insert(adj);
}
La classe :
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; }
}
Carte de la classe :
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();
}
}
Suis-je raté quelque chose?
Une idée de comment accélérer les inserts?
Les requêtes générées sera la même que ci-dessous :
source d'informationauteur Javid_p84
Vous devez vous connecter pour publier un commentaire.
de l'apparence de votre NHProf résultats que vous êtes en utilisant de l'identité comme votre POID. Par conséquent, vous ne pouvez pas profiter de lots écrit. chaque insert/update/delete est une commande séparée. c'est pourquoi il est si long.
si vous modifiez votre POID à hilo, guid ou le guid.peigne et de définir la taille des lots de 500 ou 1000, alors vous verrez une amélioration drastique dans le temps d'écriture.
Je suis en supposant que vous utilisez SQL Server 2008.
Quelques choses qui viennent à l'esprit. Êtes-vous à l'aide de la clef d'identité (sélectionnez SCOPE_IDENTITY() dans votre exemple de sortie) comme clé primaire de votre entités? Si oui, alors je crois que NHibernate a pour exécuter le SCOPE_IDENTITY() pour chaque objet avant que l'objet est en fait enregistré dans la base de données. Donc, si vous êtes l'insertion de 1000 objets Nhibernate va générer 1000 instructions INSERT et 1000 sélectionnez SCOPE_IDENTITY() consolidés.
Je ne suis pas sûr à 100% mais il pourrait également pause le traitement par lots. Puisque vous utilisez NHProf alors que faut-il dire? Elle montre également que tous les états sont regroupées ou vous pouvez sélectionner individuellement les instruction INSERT dans le NHProf l'INTERFACE utilisateur? Si les semelles ne sont pas groupées, alors vous verrez probablement un Grand nombre de personne écrit" alerte dans NHProf.
Edit:
Si vous ne pouvez pas changer d'identité de génération, alors vous pourriez utiliser SqlBulkCopy. Je l'ai utilisé avec NHibernate dans la migration des données, et cela fonctionne. Ayende Rahien a exemple sur son blog laquelle vous avez commencé.