2009-06-11 16 views
10

私は現在NHibernateを使用しています。私は、このようなデータベースにレコードの束を保存する必要がある状況があります。一度に1000 +レコードをデータベースに保存する

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を使うのが良いですか?

ありがとう

+0

David Pの回答を問題の解決策として受け入れます。 –

答えて

12

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(); 
      } 
      
+0

もう少し詳しく教えてもらえますか? – Micah

+1

なぜm_configurationを設定していますか?私はSetBatchSizeにまだエラーがあり、私はその理由を理解しようとしていました。私はOracleを使用しています、多分それはバッチサイズをサポートしていませんか? –

1

DataSet? No. バルク挿入?はい。

多くのレコードを挿入していて、挿入がかなり単純な場合は、一括挿入を行い、ORMを引き出す必要があります。

+0

もう少し詳しく説明できますか?以前はバルクのインサートを扱ったことがありませんでした。ありがとう! – Micah

1

レコードを挿入する最も速い方法は、テキストファイルを生成し、LOAD FILE構文を使用することです。ほとんどのデータベースは、データファイルをデータベースにインポートするための非常に高速な実装を備えています。 、他のデータベースについては

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

を適切なマニュアルを参照してください:MySQLの場合、以下を参照してください。これは、100万レコードまたは数千のレコードを頻繁に挿入する場合に便利です。それ以外の場合は、1000個の挿入を持つ大きなSQLを作成し、ORMとその関連する検証をスキップしてデータベース接続で直接実行してください。

3

状況に応じていくつかのオプションがあると思います。

NHibernate 2.1のアルファを使用できる場合、利用可能な新しい実行可能ファイルHQLの使用を試みることができます。

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

トビアスの答えも同様に動作します。バッチサイズを設定するだけで、パフォーマンスが向上します。 SQL Serverでは一括挿入を行う

あなたはADO.Netで汚れ手にしたい場合は...

は、SQL一括コピーを使用することによって可能です。

ことの例はここにある:http://dotnetslackers.com/articles/ado_net/SqlBulkCopy_in_ADO_NET_2_0.aspx

私にはあなたは、データベース内の別のエンティティのオフに基づいて、新しいエンティティを作成しているように思えます。私にとっては、ストアドプロシージャを使用するのが理想的なシナリオのようです。

4

私は、これはあなたが探しているものであると信じて:

Bulk Data Operations With NHibernate's Stateless Sessions

代わりにISessionを開く基本的に、あなたはIStatelessSessionを開き、あなたのhibernate.cfg.xmlであなたが設定することができます。

<property name="adonet.batch_size">100</property> 
関連する問題