7

議論のために、SQL 2005/8 用としましょう。SELECTステートメントを調整するためにテーブルにインデックスを配置する場合、これらのインデックスはINSERT/ UPDATE/DELETEアクション中に維持する必要があることを理解しています。

私の主な質問はこれです:

SQL Server がテーブルのインデックスを維持するのはいつですか?

私は多くのその後の質問があります:

コマンドが実行された後にそうすると単純に思います。20 行を挿入するとします。20 行が挿入されてコミットされた後、インデックスは維持されます。

  • スクリプトがテーブルに対して複数のステートメントを備えているが、それ以外は別個のステートメントである場合はどうなりますか?

  • サーバーには、すべてのステートメントが実行された後にインデックスを維持するインテリジェンスがありますか?それとも、ステートメントごとに行いますか?

INSERT大規模な/多くの/UPDATEアクション の後にインデックスが削除され、再作成される状況を見てきました。

  • ほんの一握りの行しか変更しない場合でも、これはおそらくテーブル全体のインデックスを再構築することになりますか?

  • 多くの小さな挿入を行うのではなく、行を収集して一時テーブルに挿入するなど、より大きなバッチに照合INSERTして アクションを実行しようとすると、パフォーマンス上の利点はありますか?UPDATE

  • 上記の行を照合することは、インデックスを削除することとメンテナンス ヒットを取得することに対してどのように積み重なるでしょうか?

質問が増えて申し訳ありません - これは私がいつも気をつけていることですが、スクリプトを調整してバランスを取ろうとすると、インデックスのメンテナンスがいつ行われるのか実際にはわかりません。

編集:パフォーマンスの問題は、挿入/更新中のデータ量とインデックスの数に大きく依存することを理解しています。繰り返しますが、議論のために、次の 2 つの状況があります。

  • 選択用に調整されたインデックスの重いテーブル。
  • インデックスライトテーブル(PK)。

どちらの状況でも、大きな挿入/更新バッチ、たとえば 10,000 行以上が発生します。

編集 2:データ セットで特定のスクリプトをプロファイリングできることを認識しています。ただし、プロファイリングでは、特定のアプローチが別のアプローチよりも高速である理由はわかりません。私は、インデックスの背後にある理論と、パフォーマンスの問題が発生する場所に興味があり、「これはそれよりも速い」という決定的な答えではありません。

ありがとう。

4

1 に答える 1

3

ステートメント (トランザクションでさえない) が完了すると、すべてのインデックスが最新になります。コミットすると、すべての変更が永続的になり、すべてのロックが解放されます。そうしないと、「知性」とは言えず、整合性に違反し、エラーが発生する可能性があります。

編集:「整合性」とは、これを意味します。コミットすると、データは誰でもすぐに利用できるようになります。その時点でインデックスが最新でない場合、誰かが間違った結果を取得する可能性があります。

バッチサイズを大きくしていくと、本来はパフォーマンスが向上しますが、その後遅くなります。独自のベンチマークを実行して、最適なバッチ サイズを見つける必要があります。同様に、インデックスを削除/再作成する方が速いかどうかを判断するには、ベンチマークを行う必要があります。

編集: 1 つのステートメントで行のバッチを挿入/更新/削除すると、インデックスはステートメントごとに 1 回変更されます。次のスクリプトは、次のことを示しています。

CREATE TABLE dbo.Num(n INT NOT NULL PRIMARY KEY);
GO
INSERT INTO dbo.Num(n)
SELECT 0
UNION ALL
SELECT 1;
GO
-- 0 updates to 1, 1 updates to 0
UPDATE dbo.Num SET n = 1-n;
GO
-- doing it row by row would fail no matter how you do it
UPDATE dbo.Num SET n = 1-n WHERE n=0;
UPDATE dbo.Num SET n = 1-n WHERE n=1;
于 2010-09-21T15:11:40.377 に答える