5

私は最近、すべてのテーブルをヒープ インデックスの使用から変換して、各テーブルにクラスター化されたインデックスが含まれるようにする必要があるというアドバイスを受けました。この戦略を実行すると、どのような結果が得られますか? たとえば、データベースを定期的に再編成することがより重要ですか? データの増加?本当に遅い挿入の危険性? PK が GUID の場合、ページ最適化の危険性はありますか? アプリケーションの顕著な速度向上? あなたの経験は何ですか?

良い答えのインスピレーションとして役立つように、stackoverflow の他のスレッドから拾った「事実」の一部を次に示します。

  1. ほぼ確実に、データベース内のすべてのテーブルにクラスター化インデックスを作成したいと考えています。テーブルにテーブルがない場合。最も一般的なクエリのパフォーマンスが向上します。
  2. クラスター化されたインデックスは、GUID では常に悪いわけではありません...それはすべて、アプリケーションのニーズに依存します。INSERT 速度は低下しますが、SELECT 速度は向上します。
  3. GUID フィールドのクラスター化インデックスの問題は、GUID がランダムであるため、新しいレコードが挿入されると、テーブルの中央にレコードを挿入するためにディスク上のデータの大部分を移動する必要があることです。
  4. GUID のクラスター化インデックスは、GUID に意味があり、関連データを互いに近くに配置することでパフォーマンスが向上する状況では問題ありません http://randommadness.blogspot.com/2008/07/guids-and-clustered-indexes.html
  5. クラスタリングは検索速度に影響しません。一意の非クラスタ化インデックスがその役割を果たします。
4

3 に答える 3

9

キーが GUID の場合、そのキーの非クラスター化インデックスは、おそらくそのキーのクラスター化インデックスと同じくらい効果的です。これは、GUID では絶対にレンジ スキャンを実行できないためです (どういうbetween 'b4e8e994-c315-49c5-bbc1-f0e1b000ad7c' and '3cd22676-dffe-4152-9aef-54a6a18d32ac'意味でしょうか??)。幅が 16 バイトの GUID クラスター化インデックス キーは、ヒープから取得する行 ID よりも幅が広いため、PK GUID の NC インデックスは実際には議論で防御できる戦略です。

ただし、ヒープ上にクラスター化インデックスを作成する方法は、主キーをクラスター化インデックス キーにすることだけではありません。特定の列の範囲を要求する他の頻繁なクエリはありますか? 典型的な候補は、、またはのようなdatestateですdeleted。その場合、それらの列をクラスター化インデックス キーにすることを検討する必要があります (一意である必要はありませ)。そうすることで、「昨日のすべてのレコード」などの範囲を要求するクエリに役立つ可能性があります。

ヒープによってパフォーマンスが大幅に向上する唯一のシナリオは、挿入、特に一括挿入です。挿入負荷がそれほど高くない場合は、間違いなくクラスター化インデックスを使用する必要があります。クラスタ化インデックスの設計ガイドラインを参照してください。

あなたのポイントを見ていきます:

ほぼ確実に、データベース内のすべてのテーブルにクラスター化インデックスを作成したいと考えています。テーブルにテーブルがない場合。最も一般的なクエリのパフォーマンスが向上します。

ほとんどのクエリの範囲要件を満たすことができるクラスター化インデックスは、パフォーマンスを大幅に向上させます。順序の要件を満たすことができるクラスター化インデックスも役立ちますが、範囲を満たすことができるものほど役に立ちません。

クラスター化されたインデックスは、GUID では常に悪いわけではありません...それはすべて、アプリケーションのニーズに依存します。INSERT 速度は低下しますが、SELECT 速度は向上します。

プローブ SELECT のみが改善されます: SELECT ... WHERE key='someguid';。オブジェクト ID によるクエリと外部キー ルックアップは、このクラスター化インデックスの恩恵を受けます。NC インデックスも同様に同じ目的を果たすことができます。

GUID フィールドのクラスター化インデックスの問題は、GUID がランダムであるため、新しいレコードが挿入されると、テーブルの中央にレコードを挿入するためにディスク上のデータの大部分を移動する必要があることです。

違う。インデックス内の位置に挿入する場合、データを移動する必要はありません。起こりうる最悪の事態は、ページ分割です。ページ分割は (どういうわけか) コストがかかりますが、世界の終わりではありません。新しい行のためのスペースを確保するために、すべてのデータ (または少なくとも「重要な」部分) を移動する必要があるとコメントしていますが、これはどこにも当てはまりません。

GUID のクラスター化インデックスは、GUID に意味があり、関連データを互いに近くに配置することでパフォーマンスが向上する状況では問題あり ません http://randommadness.blogspot.com/2008/07/guids-and-clustered-indexes.html

GUID が「関連データ」を持つことができるシナリオを想像することはできません。GUID は典型的なランダム構造であり、どのようにして 2 つのランダム GUID を関連付けることができるのでしょうか? Donald が提供するシナリオには、より優れた解決策があります: Resolving PAGELATCH Contention on Highly Concurrent INSERT Workloadsは、実装が安価であり (必要なストレージが少ない)、一意のキーでも機能します (リンクされた記事のソリューションは、一意のキーでは機能せず、外部の場合のみ機能します)。キー)。

クラスタリングは検索速度に影響しません。一意の非クラスタ化インデックスがその役割を果たします。

プローブの場合 (特定の一意のキーを検索) はい。NC インデックスは、クラスター化されたインデックスとほぼ同じくらい高速です (NC インデックス ルックアップには、残りの列をフェッチするための追加のキー ルックアップが必要です)。クラスター化インデックスが優れているのは範囲スキャンです。クラスター化インデックスはすべてのクエリをカバーできるためです。同じ範囲を満たす可能性のある NC インデックスは、カバレッジが緩み、インデックス ティッピング ポイントをトリガーする可能性があります。

于 2010-12-13T21:35:26.957 に答える
2

また、Kimberly Tripp のThe Clustered Index Debate Continues...を読むことをお勧めします。その中で彼女は、ヒープよりも優れたクラスタリング キーを持つことのすべての利点を明確に説明しています。

ほぼすべての操作が高速化されました -はい! 挿入や更新も!

ただし、これには適切なクラスタリング キーが必要であり、非常にランダムで予測不可能な性質を持つ GUID は、クラスタリング キーの適切な候補とは見なされません。クラスタリング キーとしての GUID は、アプリケーションの意味があるかどうかに関係なく、悪いものです。それらは避けてください。

あなたの最善の策は、狭く、安定しており、ユニークで、増え続けるキーです。タイプの列は、INT IDENTITYこれらすべての要件を理想的に満たします。

GUID が適切なクラスタリング キーにならない理由と、GUID がどれほど悪いかについての詳細な背景については、Kim Tripp のブログ投稿を参照してください。

于 2010-12-13T22:04:20.473 に答える
1

「SQL Performance Explained」という本をお勧めします。インデックスに関する 200 ページの本です。

また、クラスター化されたインデックスが通常のインデックスよりもパフォーマンスが悪い場合についても説明します。問題の 1 つは、クラスター化インデックス自体が B ツリーであることです。したがって、同じテーブルに他のインデックスがある場合、それらは特定の行を指すことはできません。代わりに、クラスター化インデックスの「キー」を指すため、データへの「道」が長くなります。

于 2012-11-20T21:34:40.627 に答える