【问题标题】:NHibernate performance insertNHibernate 性能插入
【发布时间】:2008-11-13 09:56:31
【问题描述】:

我正在使用 nhibernate 进行一些测试,并且正在修改 batch_size 以获取批量插入。

我正在使用 mssql2005 并使用北风数据库。 我创建了 1000 个对象并将它们插入数据库。我已将 batch_size 的值从 5 更改为 100,但发现性能没有变化。我得到大约 300 毫秒的值。使用 sql profiler,我看到服务器端有 1000 条 sql insert 语句。请帮忙。

app.config

 <property name="adonet.batch_size">10</property>

代码

    public bool MyTestAddition(IList<Supplier> SupplierList)
    {
        var SupplierList_ = SupplierList;
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        using (ISession session = dataManager.OpenSession())
        {  
            int counter = 0;
            using (ITransaction transaction = session.BeginTransaction())
            {

                foreach (var supplier in SupplierList_)
                {
                    session.Save(supplier);                       
                }
               transaction.Commit(); 
            }

        }
        stopwatch.Stop();
        Console.WriteLine(string.Format("{0} milliseconds. {1} items added",
                            stopwatch.ElapsedMilliseconds,
                            SupplierList_.Count));
        return true;
    }

【问题讨论】:

    标签: nhibernate


    【解决方案1】:

    以下是一篇关于 Hibernate 批处理的精彩文章,它是 NHibernate 的基础并紧随其后:

    http://relation.to/Bloggers/BatchProcessingInHibernate

    如您所见,建议的操作是在配置中设置合理的批量大小,您已经完成了,但也每隔 20 条左右的记录调用session.flush()session.clear()

    我们自己采用了这种方法,现在可以在几秒钟内创建和保存 1000 多个对象。

    【讨论】:

    • 您答案中的链接给出了 404,还有其他链接吗?谢谢!
    • 互联网上没有真正的消亡。这是页面的 Google 缓存:goo.gl/JCSm1
    • @ChrisAnnODell: 现在好像死了:)
    • 但是原版还活着! :D
    【解决方案2】:

    您可以将目标类型加载到 List,然后调用 System.Data.SqlClient.BulkCopy 将数据 bcp 到目标表中。

    这将允许处理更大的卷。

    【讨论】:

      【解决方案3】:

      根据this nhusers post,您在 SQL Server 中看到 1000 次插入并不重要,因为优化是在不同的级别上完成的。如果您确实没有提高性能,尝试最新版本的 NHibernate 可能有助于解决问题。

      【讨论】:

        【解决方案4】:

        我用 nh 尝试过类似的东西,但从未真正获得过出色的性能。我记得每 10 个条目刷新一次,每 50 个条目提交一次,以提高性能,因为每次插入过程都会逐渐变慢。这实际上取决于对象的大小,因此您可以使用这些数字来玩弄,也许您可​​以从中挤出一些性能。

        【讨论】:

          【解决方案5】:

          调用 ITransaction.Commit 将刷新您的会话,有效地将您的更改写入数据库。您在每次保存后调用 Commit,因此每个供应商都会有一个 INSERT。

          我会尝试在每 10 个左右的供应商之后调用 Commit,或者甚至在你的 1000 个供应商结束时调用!

          【讨论】:

          • 实际上 commit() 在 foreach 循环之外。所以这意味着它在 1000 次插入结束时被调用
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多