私は30ファイルのセットを持っています。私はこれらのファイルをループし、それぞれについて約30列、およそ6列を含む219487行を挿入する1529行を挿入します。SQLサーバーのパフォーマンスが低下する理由は何ですか?
私はこれをC#で行い、データテーブル(下を参照)を使用して挿入します。私は、1529行(30列)のバッチごとに1,300行と219,487行(6列)のバッチごとに50000にグループ化しました。
各バッチを挿入するときには、マルチスレッド化はありません。すべてが(少なくとも私のコードでは)シーケンシャルです。私のコード行が前のファイルの挿入を完了するまで、次のファイルを開始しません。
これを念頭に置いて、私はSQLサーバーが一定の時間内に各ファイルを完成することを期待しています(ファイルは非常に似ていますが、常に1529と219487の挿入です)。
ただし、ファイルごとの各SQL挿入に要する時間は、最初のファイルの9秒から30番目のファイルの50秒に直線的に増加します。私は取ったSQL時間からCPU時間を分けており、最初は6列の行の1つを挿入するのに0.000033秒かかっています。最後に、後のファイルの場合、6列のデータの場合は、0.000228になります。つまり、219,487行(6列)のデータを挿入するのにかかる時間が約7倍になりましたか?
バッチサイズを20000に減らしても差はありませんでした。過去に私はそれを5000と10000に減らしたと信じていましたが、それはまだ何の違いもありませんでした。基本的なSQLアーキテクチャについてはあまりよく分かりませんので、少し失われています。
私はSQLサーバーに過負荷を感じています。しかし、これはSQLサーバーにジョブを渡すのではなく、順次実行されているという印象の下にあったのでしょうか? SQLリクエストがスレッドによって生成される可能性はありますが、バッチサイズを100に減らしています(さらに下を参照)。これはまだ助けにはなりません。完了までの全体の時間は長くなりましたが、それでもファイルごとに直線的に増加しました。
私はバッチサイズを100に減らしました(サーバーが過負荷にならないようにするため)、私はまだ直線的に増加する時間を見ていますか?
私はSQLの挿入に要した時間を指していましたが、1ファイルあたりのSQL + CPU時間の合計ではありません。
何が起こっているのか正確にアドバイスすることは不可能でしょうが、これを修正する可能性があることを間違いなく避けるためのヒントやものがありますか?
(各バッチ挿入ごとに呼ばれる)マイ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();
}
}
}
単純なinsert文のクエリプランを取得しますか? – mezamorphic
実際には、しかし、実行された計画にトリガが現れた場合、そのことが分かります。それは簡単な挿入のように見えるかもしれませんが、処理のトンをトリガします。 – TomTom
私がSQLアーキテクチャを教えたとき、私はSQLがどのように特定のクエリプランではないのかということを意味しました:) – mezamorphic