5

速度を最適化したい次の(簡略化された)コードがあります。

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 自体に値を代入するのが遅いことがわかりました。

DataTables の仕組みがわからないので、最初に再利用可能な配列を作成し、それを DataRow に割り当ててから DataRow を DataTable に追加することで、不要なオーバーヘッドを作成しているのではないかと考えています。それとも、そもそも DataTable の使用は最適ではありませんか? 入力はデータベースから取得されます。

私はLOCについてはあまり気にしません。速度だけです。誰でもこれについてアドバイスできますか?

4

3 に答える 3

13

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

public void WriteToServer(IDataReader reader)

方法。

コードで「偽の」IDataReaderインターフェースを自分で実装する必要があることを意味する場合があります (既存の からデータを取得しない場合IDataReader)。 2億ループを回避します。

于 2011-02-01T08:10:30.730 に答える
4

巨大なデータ テーブルをメモリに保持する代わりにIDataReader、一括コピーが進むにつれてデータを提供する を実装することをお勧めします。これにより、事前にすべてをメモリに保持する必要がなくなり、パフォーマンスが向上します。

于 2011-02-01T08:11:53.980 に答える
0

データテーブル全体をメモリ内に構築しないでください。DataRow の配列を取る WrtieToServer のこのオーバーロードを使用します。データをチャンクに分割するだけです。

于 2011-02-01T08:09:27.813 に答える