8

ようやく挿入バッチが機能するようになり、バッチのサイズをいじっていますが、50 の値と 10000 の値の間にパフォーマンスの違いは見られません。これは非常に奇妙に思えます。裏で何が起きているか分からないので、それが正常な動作なのかもしれません。

テーブルに 16 万行を挿入していますが、テストした値の平均時間は 115 +/- 2 秒です。バッチ処理なしで 210 秒かかるので、この改善には非常に満足しています。ターゲット テーブルは次のとおりです。

CREATE TABLE [dbo].[p_DataIdeas](
    [wave] [int] NOT NULL,
    [idnumber] [int] NOT NULL,
    [ideaID] [int] NOT NULL,
    [haveSeen] [bit] NOT NULL CONSTRAINT [DF_p_DataIdeas_haveSeen]  DEFAULT ((0)),
  CONSTRAINT [PK_p_DataIdeas] PRIMARY KEY CLUSTERED 
(
  [wave] ASC,
  [idnumber] ASC,
  [ideaID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON
) ON [PRIMARY]
) ON [PRIMARY]

UpdateBatchSize を設定するときに何を探すべきかを読みましたが、答えはいくつかの異なる値を単純にテストすることでした。それは理解できますが、テーブルの設計、SQL の質問、および挿入しようとしているデータを知っていれば、適切な値を計算するか、少なくとも推測することは可能ではないでしょうか?

誰かが推奨できるベストプラクティスはありますか?

4

3 に答える 3

8

バッチ処理の効果は、SQL プロファイラを参照するか、 を呼び出すことで確認できますSqlConnection.RetrieveStatistics()。各バッチが DB への 1 回の往復に対応していることがわかります。

バッチ サイズを最適化する方法に関しては、非常に大まかな経験則として、バッチ サイズが約 50 を超えるとパフォーマンスの向上が止まる傾向があります。忙しすぎてテストできない場合は、通常、約 20 のバッチから開始します (テーブル値パラメーターを使用していない限り、最大 500 のバッチの方が小さいバッチよりも高速である可能性があります)。ただし、最適な数は、挿入の合計サイズ (すべてが RAM に収まるか)、DB ログが配置されているディスクの速度、ログが独自のドライブ/LUN にあるかどうかなどによって異なります (そうでない場合は大きなパフォーマンス コストがかかる)など。

達成可能な速度は、通常、最初にラウンド トリップの数によって制限され、次にトランザクション サイズ、次にログ ディスクの速度によって制限されます (特に、シーケンシャル アクセスが可能かどうか、または同じスピンドル上の他のファイルとの競合のためにランダムに強制されるかどうか)、最後に羊。ただし、すべての要因はある程度相互に関連しています。

挿入のパフォーマンスを改善するための最初のステップは、トランザクションでそれらを実行することです。おそらく、バッチごとに 1 つまたは 2 つのトランザクションです。それを超えて、テーブル値パラメーターはおそらく次のステップであり、INSERT INTO Table SELECT column FROM @TableArgument.

于 2011-12-02T15:12:57.477 に答える
1

UpdateBatchSize を変更するとある程度は効果がありますが、DataAdapter を使用して多数のレコードを更新する基本的な方法は遅くなります。これは、最終的に、行ごとに個別の SQL ステートメント (挿入、更新、または削除) が DataAdapter によって生成されるためです。UpdateBatchSize は、SQL Server に送信されるときに 1 つの TSQL バッチで送信される個々のステートメントの数にのみ影響します。

パフォーマンスを大幅に向上させるには、SQLServer で 1 つのステートメントで多くのレコードを挿入/更新/削除する必要があります (通常は何らかの JOIN を使用します)。テーブル値パラメーター (RickNZ が言及) は、これを行う 1 つの方法です。もう 1 つの可能性は、SqlBulkCopy を使用することです (通常、これにはステージング テーブルを使用する必要があります)。

于 2011-12-03T00:22:51.280 に答える