2011-01-18 10 views
1

私は1.400.000エントリのテーブルを持っています。そのドキュメント多くの行を高速化するにはどうすればいいですか

表の単純なリストである - ドキュメント

  • ID int型
  • DocumentPathのデータ型はnvarchar
  • DocumentValid ビット

私は、ディレクトリをスキャンし、で見つかった文書を設定しますディレクトリは有効です。

public void SetReportsToValidated(List<int> validatedReports) 
    { 
     SqlConnection myCon = null; 

     try 
     { 
      myCon = new SqlConnection(_conn); 
      myCon.Open(); 

      foreach (int id in validatedReports) 
      {      
       SqlDataAdapter myAdap = new SqlDataAdapter("update_DocumentValidated", myCon); 
       myAdap.SelectCommand.CommandType = CommandType.StoredProcedure; 

       SqlParameter pId = new SqlParameter("@Id", SqlDbType.Int); 
       pId.Value = id; 
       myAdap.SelectCommand.Parameters.Add(pId); 

       myAdap.SelectCommand.ExecuteNonQuery(); 
      } 
     } 
     catch (SystemException ex) 
     { 
      _log.Error(ex); 
      throw; 
     } 
     finally 
     { 
      if (myCon != null) 
      { 
       myCon.Close(); 
      } 
     } 
    } 

アップデートのパフォーマンスは問題ありませんが、もっと必要です。有効な文書の1000000を更新するのに1時間以上かかります。アップデートをスピードアップする良い方法はありますか?私はバッチのいくつかの種類(テーブル値のようなパラメータ)を使用することを考えています。 SQLServerでプロファイルを作成すると、各更新に約5-10msかかる。

答えて

2

レポートを読み込んで一緒にDataTableに追加します(次元が同じであるため)SqlBulkCopyオブジェクトを使用して全体をアップロードします。おそらくあなたのためにうまくいくでしょう。少数の列と行が与えられても、メモリの問題は発生しません。代わりにアダプタを作成する

+0

私はバルク・コピーのためのDataTableを使用することができることを名言を知っていました。これはうまくいきました:一時テーブルへの挿入が40秒に短縮されましたhttp://msdn.microsoft.com/en-us/library/ex21zs8x.aspx –

+0

これは助けてくれてうれしい! –

0

と一度だけそれらを作成し、パラメータに異なる値を割り当てるループ内のすべての時間をパラメータ:

  SqlDataAdapter myAdap = new SqlDataAdapter("update_DocumentValidated", myCon); 
      myAdap.SelectCommand.CommandType = CommandType.StoredProcedure; 

      SqlParameter pId = new SqlParameter("@Id", SqlDbType.Int); 
      myAdap.SelectCommand.Parameters.Add(pId); 

      foreach (int id in validatedReports) 
      { 
       myAdap.SelectCommand.Parameters[0].Value = id; 
       myAdap.SelectCommand.ExecuteNonQuery(); 
      } 

これは非常に劇的な改善をもたらすが、に比べて優れていない可能性があります元のコード。また、SqlCommandオブジェクトを手動で実行しているので、アダプタはまったく必要ありません。 SqlCommandを直接使用してください。

2

現在、個々のレコードごとにdbを呼び出しています。あなたは(非常に簡単な一言で言えば)で一括更新を行うためにSqlDataAdapterオブジェクトを使用することができます。

1)を定義する1つのSqlDataAdapterを)は、あなたの更新SPROCを
3に、アダプタに.UpdateCommandを設定).Updateを呼び出しますメソッドを使用して、更新するドキュメントのIDを含むDataTableを渡します。これにより、DataTableの更新された行がDBにバッチアップされ、バッチ処理された各レコードのsprocが呼び出されます。 .BatchSizeプロパティを使用してバッチサイズを制御することができます。
4)これは、バッチ更新では効率が悪いマニュアルを削除することです。

例を参照してください:あなたはできる代わり
http://support.microsoft.com/kb/308055
http://www.c-sharpcorner.com/UploadFile/61b832/4430/


を:データベース(高効率で新しいテーブルにすべてのIDを挿入バルクに
1)使用SqlBulkCopy)
2)そのステージング・テーブルにロードされたら、単一のSQL文を実行して、そのステージング・テーブルからメイン・テーブルを更新してドキュメントを検証します。

は、例を参照してください:
http://www.adathedev.co.uk/2010/02/sqlbulkcopy-bulk-load-to-sql-server.html
http://www.adathedev.co.uk/2011/01/sqlbulkcopy-to-sql-server-in-parallel.html

関連する問題