web-dev-qa-db-ja.com

すべてのユーザーテーブルにクラスター化インデックスが必要ですか?

最近、クラスター化インデックスが定義されていないデータベースでいくつかのテーブルを見つけました。ただし、非クラスター化インデックスが定義されているため、それらはHEAP上にあります。

分析の結果、selectステートメントが非クラスター化インデックスで定義された列にフィルターを使用していることがわかりました。

これらのテーブルにクラスター化インデックスがないと、パフォーマンスに影響しますか?

24
Sreedhar

これをSQLServer MVPよりも簡潔に述べるのは難しいです Brad McGehee

経験則として、すべてのテーブルにはクラスター化インデックスが必要です。常にではありませんが、一般的に、クラスター化インデックスは単調に増加する列(ID列、または値が増加している他の列など)で、一意です。多くの場合、主キーはクラスター化インデックスの理想的な列です。

[〜#〜] bol [〜#〜] この感情を反映しています:

いくつかの例外を除いて、すべてのテーブルにはクラスター化インデックスが必要です。

これを行う理由はたくさんあり、主にクラスター化インデックスがストレージ内のデータを物理的に順序付けるという事実に基づいています。

  • クラスタ化インデックスが単一の列にある場合、単調に増加し、ストレージデバイスで順番に挿入が行われ、ページ分割は行われません。

  • クラスター化インデックスは、主キーに基づいて行を選択する一般的なパターンなど、インデックス値が一意である場合に特定の行を見つけるのに効率的です。

  • クラスター化インデックス 多くの場合 は、値の範囲(between、_>_など)で頻繁に検索される列に対する効率的なクエリを可能にします。

  • クラスタリングにより、データが特定の1つまたは複数の列で一般的に並べ替えられるクエリを高速化できます。

  • クラスター化インデックスは、テーブルの断片化を制御するために、オンデマンドで再構築または再編成できます。

  • これらの利点は ビューに適用 でさえあり得ます。

次の場所にクラスター化インデックスを設定したくない場合があります。

  • SQL Serverはストレージ内のデータを物理的に並べ替える必要があるため、データが頻繁に変更される列。

  • すでに他のインデックスでカバーされている列。

  • クラスター化インデックスは非クラスター化インデックスルックアップでも使用されるため、ワイドキー。

  • GUID列は、IDよりも大きく、事実上ランダムな値(ソートされる可能性は低い)ですが、 newsequentialid() を使用すると、挿入中の物理的な並べ替えを軽減できます。

  • ヒープ (クラスター化インデックスのないテーブル)を使用するまれな理由は、データが常に非クラスター化インデックスを介してアクセスされ、RID(SQL Server内部行識別子)がクラスター化インデックスよりも小さいことがわかっている場合です。キー。

これらの考慮事項や特定のアプリケーションワークロードなどの他の考慮事項があるため、クエリで最大のメリットを得るには、クラスター化インデックスを慎重に選択する必要があります。

また、SQL Serverのテーブルに主キーを作成すると、デフォルトで一意のクラスター化インデックスが作成されることに注意してください(まだ作成されていない場合) 1つ持っています)。つまり、クラスター化インデックスを持たないが、(すべてのテーブルがそうであるように)主キーを持っているテーブルを見つけた場合、開発者は以前にその方法で作成することを決定していました。あなたはそれを変えるための説得力のある理由が欲しいかもしれません(私たちが見てきたように、その多くがあります)。 クラスター化インデックスを追加、変更、または削除するには、テーブル全体と非クラスター化インデックスを書き換える必要があるため、大きなテーブルでは時間がかかる場合があります。

49
Tim Lehner

「すべてのテーブルにクラスター化インデックスが必要」とは言いません。「すべてのテーブルとそのア​​クセス方法を注意深く見て、クラスター化インデックスを定義してみてください意味がある場合 "。それはプラスです、ジョーカーのように、あなたはテーブルごとに1つのジョーカーしか持っていません、しかしあなたはそれを使用しませんしなければなりません。他のデータベースシステムには、少なくともこの形式では、これがありません。

たとえば、クラスター化インデックスをどこにでも配置しても、パフォーマンスが低下する可能性があります(一般に、クラスター化インデックスはディスク上での物理的な並べ替えを意味するため、INSERTパフォーマンス、または少なくともそれを理解するための良い方法です)。ますます多く見られるように、GUID主キーを使用します。

それで、ティム・レーナーの例外と理由を読んでください。

3
Simon Mourier

パフォーマンスは大きな問題です。正しいことを最適化していることを確認してください。

無料のアドバイスは常にその価格の価値があり、実際の実験に代わるものはありません。

インデックスの目的は、一致する行を検索し、見つかったときにデータを取得できるようにすることです。

検索条件の非クラスター化インデックスは行を見つけるのに役立ちますが、行のデータを取得するには追加の操作が必要です。

クラスタ化インデックスがない場合、SQLは内部rowIdを使用してデータの場所を指します。

ただし、テーブルにクラスター化インデックスがある場合、そのrowIdはクラスター化インデックスのデータ値に置き換えられます。

したがって、行データを読み取るステップは不要であり、インデックスの値でカバーされます。

クラスター化インデックスの選択があまり得意ではない場合でも、それらのキーが要求される結果のほとんどまたはすべてであることが多い場合は、それらを非クラスター化インデックスのリーフとして使用すると役立つ場合があります。

1
Rawheiser

はい、すべてのテーブルにクラスター化インデックスが必要です。クラスター化インデックスは、テーブル内のデータの物理的な順序を設定します。これを、バンド名や姓で並べ替えられたイエローページで、店舗での音楽の注文と比較できます。これは物理的な順序を扱っているため、1つしか持つことができず、多くの列で構成できますが、1つしか持つことができません。

値の範囲を頻繁に検索する列にクラスター化インデックスを配置することをお勧めします。例は日付範囲です。クラスター化インデックスは、インデックス値が一意である場合に特定の行を見つけるのにも効率的です。 Microsoft SQLは、クラスター化インデックスが定義されていない場合、クラスター化インデックスをPRIMARY KEY制約に自動的に配置します。

クラスター化インデックスは、次の場合には適していません。

頻繁に変更される列

  • これにより、行全体が移動します(SQL Serverは行のデータ値を物理的な順序で保持する必要があるため)。これは、データが不安定になる傾向がある大量のトランザクション処理システムで重要な考慮事項です。

ワイドキー

  • クラスター化インデックスのキー値は、すべての非クラスター化インデックスによってルックアップキーとして使用されるため、各非クラスター化インデックスリーフエントリに格納されます。
1
LCarter

はい、テーブルにクラスター化インデックスが必要です。これにより、すべての非クラスター化インデックスのパフォーマンスが向上します。

1
AnandPhadke

多数の個別の値を含む列の場合は、clustered indexの使用を検討してくださいSQL Serverがキー値を複製するために「一意化子」を追加する必要をなくすため

デメリット:クラスタリングインデックスのフィールドが変更された場合のみ、レコードの更新に時間がかかります。

クラスタリングインデックスを回避ほぼ同じクラスタリングインデックス値で多数の同時挿入が発生するリスクがある構造

非クラスター化インデックスに対する検索は、クラスター化インデックスが正しく構築されていないか、データを呼び出し元のアプリケーションに返すために必要なすべての列が含まれていない場合、遅く表示されます。非クラスター化インデックスに必要なすべてのデータが含まれていない場合、SQL Serverはクラスター化インデックスに移動して(ルックアップを介して)欠落しているデータを取得します。これにより、ルックアップが実行されるときにクエリの実行が遅くなります。行ごと。

0
user1499112