私は30個のファイルのセットを持っています。これらのファイルをループし、それぞれに約 30 列の 1529 行と、約 6 列の 219487 行を挿入します。
私はC#でこれを行っており、データテーブルを介して挿入しています(下を参照)。挿入を、1529 行 (30 列) の場合はバッチあたり 1,300 行、219,487 行 (6 列) の場合はバッチあたり 50000 行にグループ化しました。
各バッチを挿入するとき、マルチスレッドはありません-すべてがシーケンシャルです(少なくとも私のコードでは)。私のコード行が前のファイルの挿入を完了するまで、次のファイルから始めません。
これを念頭に置いて、SQL サーバーが一定時間内に各ファイルを完了することを期待します (ファイルは非常に似ており、常に 1529 回と 219487 回の挿入です)。
ただし、ファイルごとの各 SQL 挿入にかかる時間は、最初のファイルの 9 秒から 30 番目のファイルに向かって 50 秒まで直線的に増加します。CPU 時間を SQL 時間から分離しました。最初は、6 列の行の 1 つを挿入するのに 0.000033 秒かかります。最後の方のファイルでは、6 列のデータの場合、所要時間は 0.000228 です。つまり、219,487 行 (6 列) のデータを挿入するのにかかる時間が約 7 倍になったのでしょうか。
バッチサイズを 20000 に減らしましたが、違いはありませんでした。過去に私はそれを 5000 と 10000 に減らしたと思いますが、それでも違いはありませんでした。基礎となる SQL アーキテクチャについてあまり知らないので、少し迷っています。
SQL サーバーに過負荷をかけているように感じます。しかし、これは SQL サーバーにジョブを与えるのではなく、順次行われているという印象を受けましたか? SQL リクエストがスレッド経由で生成される可能性がありますが、バッチ サイズを 100 に減らしても (以下を参照)、それでも役に立ちませんでした。完了するまでの全体的な時間は長くなりましたが、それでもファイルごとに直線的に増加しました。
バッチ サイズを 100 に減らしました (サーバーが過負荷にならないようにするため)。
全体を通して、ファイルごとの SQL 時間と CPU 時間の合計ではなく、SQL 挿入にかかった時間を参照してきました。
何が起こっているのか正確にアドバイスすることはおそらく不可能でしょうが、これを最善の方法で修正するために絶対に避けるべきヒントや事柄を教えてもらえますか?
私のSQL挿入コード(バッチ挿入ごとに呼び出される)は次のとおりです。
private static void WriteResultsToDatabase(string tableName, DataTable tableToWrite)
{
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlBulkCopy bulkCopy =
new SqlBulkCopy
(
connection,
SqlBulkCopyOptions.TableLock |
SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.UseInternalTransaction,
null
);
bulkCopy.DestinationTableName = tableName;
for (int i = 0; i < tableToWrite.Columns.Count; i++)
bulkCopy.ColumnMappings.Add(tableToWrite.Columns[i].ColumnName, tableToWrite.Columns[i].ColumnName);
try
{
connection.Open();
bulkCopy.WriteToServer(tableToWrite);
}
finally
{
connection.Close();
}
}
}