DataTableを使うよりもSqlBulkCopyを使う方が速いのですか?

c# sqlbulkcopy sql-server

質問

私は大量のレコードを自分のアプリケーションにロードして(100万+)、それらに対して処理を行います。処理には、すべてがメモリに格納されている必要があります。

その後、私はすべての(今変更された)レコードを空のテーブルにダンプします。

レコードの読み込みにはほんの数秒しかMyRecordMyRecord項目の大きな配列にMyRecordます。

SqlBulkCopyを使用した保存には数秒SqlBulkCopyかかりません。

しかし、 SqlBulkCopyDataTableを必要とします(私は信じていDataTable )。そして、 DataTableへの私のレコードのロードは遅いです - 毎分約7500レコード

dataTable.Rows.Add(myRecord.Name, myRecord.Age, ....)

この中間ステップをより速く実行する方法はありますか?

受け入れられた回答

遅延は、すべてをDataTableにバッファリングしてからサーバーに送信する必要があるために発生します。パフォーマンスを向上させるには、レコードをSqlBulkCopy immediatellyに送信し、クラスに独自のバッファリングとバッチ処理を使用させる必要があります。

SqlBulkCopyはIDataReaderで動作します。すべてのADO.NETデータリーダーがこのインターフェイスを実装しているので、データリーダーから読み取ったデータをSqlBulkCopyにプッシュできます。

他のケースでは、オブジェクトのIEnumerableがあると仮定すると、 FastMemberパッケージのMarc GravelのObjectReaderを使用して、IEnumerableの上にIDataReaderを作成できます。このデータリーダーはすべてを一度に読み込むわけではないので、SqlBulkCopyが要求するまでデータはキャッシュされません。

Marc Gravelの例をコピーする:

IEnumerable<SomeType> data = ... 

using(var bcp = new SqlBulkCopy(connection)) 
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description")) 
{ 
  bcp.DestinationTableName = "SomeTable"; 
  bcp.WriteToServer(reader); 
}

人気のある回答

私はその問題が何であるか分からない。以下のプログラムは1秒未満で実行されます。私は、遅い速度がデータの読み取りとDataTableへの書き込みではないと思われます。

       static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Col A", typeof(int));
            dt.Columns.Add("Col B", typeof(string));
            dt.Columns.Add("Col C", typeof(int));
            dt.Columns.Add("Col D", typeof(string));
            dt.Columns.Add("Col E", typeof(int));
            dt.Columns.Add("Col F", typeof(string));
            dt.Columns.Add("Col G", typeof(int));
            dt.Columns.Add("Col H", typeof(string));
            dt.Columns.Add("Col I", typeof(int));
            dt.Columns.Add("Col J", typeof(string));

            DateTime begin = DateTime.Now;

            for (int i = 0; i < 7500; i++)
            {
                dt.Rows.Add(new object[] {
                    i + 10000, "b", i + 20000, "d", i + 30000, "f", i + 40000, "h", i + 50000, "i"
                });
            }

            DateTime end = DateTime.Now;

            Console.WriteLine((end - begin).ToString());

            Console.ReadLine();
        }


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow