C#の最適化:データベースに2億行を挿入

c# datatable sqlbulkcopy

質問

私は速度のために最適化したいと思う次の(簡略化された)コードがある:

long inputLen = 50000000; // 50 million 
DataTable dataTable = new DataTable();
DataRow dataRow;
object[] objectRow;
while (inputLen--)
{
    objectRow[0] = ...
    objectRow[1] = ...
    objectRow[2] = ...

    // Generate output for this input
    output = ...

    for (int i = 0; i < outputLen; i++) // outputLen can range from 1 to 20,000
    {
         objectRow[3] = output[i];
         dataRow = dataTable.NewRow();
         dataRow.ItemArray = objectRow;
         dataTable.Rows.Add(dataRow);
    }
}

// Bulk copy
SqlBulkCopy bulkTask = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null);
bulkTask.DestinationTableName = "newTable";
bulkTask.BatchSize = dataTable.Rows.Count;
bulkTask.WriteToServer(dataTable);
bulkTask.Close();

私はすでにSQLBulkCopyを使って処理を高速化しようとしていますが、DataTable自体に値を割り当てることは遅いことがわかります。

私はDataTableの仕組みがわからないので、最初に再利用可能な配列を作成し、それをDataRowに割り当て、次にDataRowをDataTableに追加することで、不要なオーバーヘッドを作成するのかどうか疑問に思っていますか?または、DataTableを最初に最適化しないで使用していますか?入力はデータベースから来ます。

私はLOCについて心配していません。スピードだけです。誰もこれについていくつかのアドバイスを与えることができますか?

受け入れられた回答

このような大きなテーブルの場合は、代わりに

public void WriteToServer(IDataReader reader)

方法。

つまり、既存のIDataReaderからデータを取得しない場合は、自分のコードとIDataReaderインターフェイスを「偽」して実装する必要がありますが、この方法では、エンドからエンドまで「ストリーミング」が得られます200万回のループを避けることができます。


人気のある回答

巨大なデータテーブルをメモリに保持するのではなく、一括コピーが進むにつれてデータをIDataReaderを実装することをお勧めします。これにより、すべてのものをメモリに保存する必要性が減り、パフォーマンスが向上するはずです。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ