【问题标题】:Inserts of stateless session of NHibernate are slowNHibernate 的无状态会话的插入速度很慢
【发布时间】:2012-01-23 16:30:59
【问题描述】:

这几天我一直致力于提高 NHibernate Insert 的性能。

我在很多帖子(例如this one)中读到无状态会话每秒可以插入大约 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();
    }
}

我错过了什么吗? 知道如何加快插入速度吗?

生成的查询将如下所示:

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate bulkinsert stateless-session


    【解决方案1】:

    从您的 NProf 结果来看,您使用身份作为您的 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,那么它说明了什么?它是否表明所有语句都是批处理的,或者您可以在 NProf UI 中选择单个 INSERT 语句?如果您的插入未批处理,那么您很可能会在 NHProf 中看到“大量单独写入”警报。

      编辑:

      如果您无法更改身份生成,则可以使用SqlBulkCopy。我已经在数据迁移中将它与 NHibernate 一起使用,并且可以正常工作。 Ayende Rahien has sample on his blog 让你开始。

      【讨论】:

      • 对于时间很重要的批量插入,我真的会选择SQLBulkCopy 解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      • 1970-01-01
      • 2022-07-28
      • 2013-04-20
      • 2016-08-21
      • 1970-01-01
      相关资源
      最近更新 更多