【问题标题】:Saving 1000+ records to the database at a time一次将 1000 多条记录保存到数据库中
【发布时间】:2010-11-02 05:01:52
【问题描述】:

我目前正在使用 NHibernate。我有一种情况,我需要像这样将一堆记录保存到数据库中:

var relatedTopics = GetRelatedTopics(topic);
foreach (var relatedTopic in relatedTopics /* could be anywhere from 10 - 1000+ */)
{
    var newRelatedTopic = new RelatedTopic { RelatedTopicUrl = relatedTopic, TopicUrl = topic.Name };
    _repository.Save(newRelatedTopic);
}

当有大量记录要保存时,必须多次访问数据库显然非常费力。有什么更好的方法?我可以做某种批量更新吗?我最好使用 DataSet 吗?

谢谢

【问题讨论】:

  • 我会接受 David P 的回答作为问题的解决方案。

标签: nhibernate ado.net batch-processing


【解决方案1】:

设置 adonet.batch_size 可以改善这种情况。

你必须这样做

  • 在 NH 配置中设置 adonet.batch_size

例子:

    m_sessionFactory = Fluently
         .Configure()
         .Database(MsSqlConfiguration
             .MsSql2005
             .ConnectionString(c => c.FromConnectionStringWithKey("testme"))
             )
         .Mappings(m => m.FluentMappings
             .AddFromAssemblyOf<TestImpl>())
         .ExposeConfiguration(config =>
         {
             config.SetProperty("adonet.batch_size", "1");
             m_configuration = config;
         })
         .BuildSessionFactory();
  • 在保存前设置会话的批量大小

    using (ISession session = m_nhibernateSessionFactory.GetSession())
    using (var tx = session.BeginTransaction())
    {    
       session.SetBatchSize(1000);     
       foreach (var server in serverz)
       {
          session.SaveOrUpdate(server);
       }
       tx.Commit();
    }
    

【讨论】:

  • 你能详细说明一下吗?
  • 为什么要设置 m_configuration?我仍然在 SetBatchSize 上收到错误,我试图找出原因。我使用的是 Oracle,可能不支持批量大小??
【解决方案2】:

数据集?不。 批量插入?是的。

如果您要插入这么多记录并且插入非常简单,则应该考虑进行批量插入并取出 ORM。

【讨论】:

  • 你能详细说明一下吗?我以前从未处理过批量插入。谢谢!
【解决方案3】:

插入记录的最快方法是生成一个文本文件并使用 LOAD FILE 语法。大多数数据库都有非常快速的实现来将数据文件导入数据库。对于 MySQL,请参见下文:

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

对于其他数据库,请参阅相应的手册。如果您经常插入一百万条记录或数千条记录,这将非常有用。否则,您能做的最好的事情就是创建一个包含 1000 次插入的大 SQL,然后直接在您的数据库连接上执行它,跳过 ORM 及其相关验证。

【讨论】:

    【解决方案4】:

    我认为您有多种选择,具体取决于您的情况。

    如果您可以使用 NHibernate 2.1 alphas,您可以尝试使用可用的新可执行 HQL。

    http://nhibernate.info/blog/2009/05/05/nh2-1-executable-hql.html

    Tobias 的回答也可以。只需设置批量大小即可显着提高性能。

    如果你想用 ADO.Net 弄脏你的手......

    可以通过使用 Sql Bulk Copy 在 Sql Server 中进行批量插入。

    这里有一个例子:http://dotnetslackers.com/articles/ado_net/SqlBulkCopy_in_ADO_NET_2_0.aspx

    在我看来,您似乎是在基于数据库中的另一个实体创建一个新实体。对我来说,这似乎是使用存储过程的理想方案。

    【讨论】:

      【解决方案5】:

      我相信这就是您正在寻找的:

      Bulk Data Operations With NHibernate's Stateless Sessions

      本质上不是打开一个 ISession,而是打开一个 IStatelessSession,在 hibernate.cfg.xml 中你可以设置:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-06
        相关资源
        最近更新 更多