web-dev-qa-db-ja.com

更新パフォーマンス:クラスター化インデックスとカバーインデックス

約5,000万行のシンプルな3列のテーブルがあります。このテーブルは1秒あたり約5,000の挿入/更新を取得し、おそらく1秒あたり20のクエリがテーブルに対して実行されます。テーブルは次のようになります。

Controller: Int
ExecutionTime: DateTime
Result: Int

クエリの効率を最大化するには、2つのインデックスが必要です。 (結果には実行時間が含まれます)および(コントローラー、実行時間)。これらの2つのインデックスは私のクエリを完全にカバーしています。すべての情報はインデックスから直接提供され、テーブルのルックアップは必要ありません。

非常に多くの更新を含むクラスター化インデックスを使用した場合のパフォーマンスへの影響が心配だったため、非クラスター化インデックスを選択しました。しかし、クエリを完全にカバーしているので、これは有効な懸念事項ではない可能性があります。おそらく、カバーしている非クラスター化インデックスは、クラスター化インデックスと同じ量のメンテナンスが必要です。

だから私の質問:挿入/更新が多いテーブルでは、カバーする非クラスタ化インデックスは通常、クラスタ化インデックスよりもUPDATEパフォーマンスヒットが低くなりますか?

お時間をいただきありがとうございます。

3
John Jeheimer

あなたの場合、非クラスター化インデックスには、テーブルの1つの列を除くすべてが含まれ、両方とも完全なレコードのサイズの3/4です(8バイトのDATETIMEを使用していると仮定)。これに基づいて、各非クラスタ化インデックスのIOコストは、クラスタ化インデックスがある場合、IOコストの約75%になります。

これで、クラスター化インデックスがないため、ヒープがあり、これは明らかにインデックスと同じように維持する必要があります。

行全体を(ヒープまたはクラスター化インデックスに)挿入するためのコストが100%であるとし、挿入中に何が発生するかを考えてみましょう。

1) insert new row into heap (cost=100%)
2) insert new row into non-clustered index #1 (cost=75%)
3) insert new row into non-clustered index #2 (cost=75%)

更新中(結果のみを更新すると想定):

1) Update the row in the heap  (cost=100%)
2) Update non-clustered index #1 (cost=75%)

挿入1回、更新1回の合計コスト= 425%

(Controller、ExecutionTime)をクラスター化するとどうなるか見てみましょう。

挿入の場合:

1) insert into the clustered index  (cost=100%)
2) insert into the non-clustered index (Result Includes Execution Time) (cost=75%)

更新の場合(結果のみを更新すると想定して、それが正しい仮定であることを期待してください):

1) update the clustered index   (cost=100%)
2) update the non-clustered index (Result Includes Execution Time) (cost=75%)

1つの挿入、1つの更新の合計コスト= 350%

したがって、書き込みに関しては、(Controller、ExecutionTime)をクラスター化してヒープを削除することは理にかなっています。

ヒープはフラグメント化で悪名高いことも言及しておきます(削除について言及しなかったため、すべての列が固定サイズであるため、問題にはならない可能性があります)。通常、OLTP =トラフィック。

4
Vlad G.

内部では、クラスター化インデックスと非クラスター化インデックスは同じです。クラスタ化インデックスには、すべての列を確実にINCLUDEする追加のプロパティがあります。したがって、データを他の場所で保守する必要はありません。したがって、更新コストの観点からは、クラスター化インデックスとすべての列を含む非クラスター化インデックスは実質的に同じです。

ただし、更新中に変更された列が含まれている場合は、すべてのインデックスを維持する必要があります。つまり、インデックスが多いほど、更新にかかるコストが高くなります。

したがって、あなたの状況では、インデックスの数を最小限に抑えるように努めます。これにより、特定のインデックスがより適切にクラスター化またはカバーされているかどうかを心配するよりも、パフォーマンスを更新できます。

つまり、更新では、できるだけ早く更新する行を見つける必要があります。選択してから2桁以上の更新があるため、インデックス付け戦略を設計するときは、最初に更新を確認する必要があります。それらが処理された後、読み取りクエリに適切なインデックスの最小数を提供することを検討してください。

4
Sebastian Meine