节省 1000+ 一次记录到数据库

发布于 2024-07-24 16:52:26 字数 452 浏览 8 评论 0原文

我目前正在使用 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);
}

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

谢谢

I'm using NHibernate currently. I have a situation where I need to save a bunch of records to the database like this:

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

When there are a ton of records to save this is obviously very taxing having to hit the database that many times. What's a better approach? Is there some sort of batch update I can do? Am I better off using a DataSet?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我一直都在从未离去 2024-07-31 16:52:26

设置 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()) 
      使用 (var tx = session.BeginTransaction()) 
      {     
         会话.SetBatchSize(1000);      
         foreach(serverz 中的 var 服务器) 
         { 
            会话.SaveOrUpdate(服务器); 
         } 
         tx.Commit(); 
      } 
      

setting adonet.batch_size could improve the situation.

For that you have to

  • set adonet.batch_size in the NH configuration

Example:

    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();
  • set the batch size on the session just before the save

    using (ISession session = m_nhibernateSessionFactory.GetSession())
    using (var tx = session.BeginTransaction())
    {    
       session.SetBatchSize(1000);     
       foreach (var server in serverz)
       {
          session.SaveOrUpdate(server);
       }
       tx.Commit();
    }
    
三岁铭 2024-07-31 16:52:26

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

使用 NHibernate 的无状态会话进行批量数据操作

本质上,您不是打开 ISession,而是打开 IStatelessSession,并且在 hibernate.cfg.xml 中您可以设置:

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

I believe this is what you are looking for:

Bulk Data Operations With NHibernate's Stateless Sessions

Essentially instead of opening an ISession, you open an IStatelessSession, and in your hibernate.cfg.xml you can set:

 <property name="adonet.batch_size">100</property>
不必在意 2024-07-31 16:52:26

我认为根据您的情况,您有多种选择。

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

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

托比亚斯的答案也有效。 只需设置批量大小即可显着提高性能。

如果您想使用 ADO.Net...

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

示例如下: http://dotnetslackers.com/articles/ado_net/SqlBulkCopy_in_ADO_NET_2_0.aspx

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

I think you have a number of options depending on your situation.

If you can use NHibernate 2.1 alphas you can try to use the new Executable HQL that's available.

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

Tobias's answer will work as well. Just setting the batch size will increase the performance respectably.

If you want to dirty your hands with ADO.Net...

Doing Bulk Inserts in Sql Server is possible through the use of Sql Bulk Copy.

An example of that is here: http://dotnetslackers.com/articles/ado_net/SqlBulkCopy_in_ADO_NET_2_0.aspx

To me it seems like you're creating a new entity based off of another entity in the database. To me that seems like an ideal scenario to use a stored procedure.

带上头具痛哭 2024-07-31 16:52:26

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

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

DataSet? No.
Bulk Insert? Yes.

If you are inserting that many records and the inserts are pretty simplistic, you should look at doing Bulk Inserts and pulling out the ORM.

遮云壑 2024-07-31 16:52:26

插入记录的最快方法是生成文本文件并使用 LOAD FILE 语法。 大多数数据库都可以非常快速地将数据文件导入数据库。 对于 MySQL,请参见以下内容:

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

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

The fastest way to insert records is to generate a text file and use LOAD FILE syntax. Most databases have remarkably fast implementations to importing data files into the databases. For MySQL, see below:

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

For other databases, refer to appropriate manual. This is useful if you are inserting a million records, or thousands of records frequently. Otherwise, the best you can do is create a big SQL with the 1000s of inserts and execute that on your database connection directly, skipping ORMs and their related validations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文