実際には、クラスター化インデックスやプライマリキーを作成する必要はありません。一意のインデックスと非一意のインデックスで作業を処理できるためです。SQL Serverは少なくともバージョン1.1以降、クラスター化インデックスをサポートしていますが、主キーは、一意のインデックスを定義することでプログラマーが実施する「概念」にすぎません。
しかし、主キーとクラスター化インデックスの両方は、ほとんどのデータベースで重要な概念のようです。
以下に示すように、SQL Serverのドキュメントを参照して、いくつかのインデックスオプションの部分的な説明を見てみましょう。
クラスター化インデックス: https : //msdn.microsoft.com/en-us/library/ms190457.aspx
- クラスター化インデックスは、キー値に基づいてデータ行を並べ替えてテーブルまたはビューに格納します。これらは、インデックス定義に含まれる列です。
- テーブルごとにクラスター化インデックスは1つしか存在できません。
主キー: https : //msdn.microsoft.com/en-us/library/ms190457.aspx
テーブルに含めることができるPRIMARY KEY制約は1つだけです。
PRIMARY KEY制約内で定義されたすべての列は、NOT NULLとして定義する必要があります。
主キーは、クラスター化インデックス(クラスター化インデックスがない場合の既定)または非クラスター化インデックスとして作成できます。
一意のインデックス: https : //msdn.microsoft.com/en-us/library/ms187019.aspx
つまり、クラスター化インデックスと主キーに関する質問は、実際には次の問題のいくつかに関するものです。すべてのテーブルが同じインデックス作成プランの恩恵を受けるわけではないことに注意してください。
主キーがクラスター化インデックスとは別のものである場合、どのようなメリットがありますか?
おそらく、クラスター化インデックスが広い場合(たとえば、5列のテキスト情報で、主キーが小さい場合(INTまたはBIGINT)、説明しているように見える場合など)。
- 幅の広いクラスター化インデックスを使用すると、クラスター化インデックス(テーブルとも呼ばれます)から連続した回答を提供するクエリのサブセットのインデックスから行をすばやく選択できます。たとえば、5列のクラスター化インデックスは、列C1、C2、C3、C4、C5またはC1、C2、C3、C4などをC1までスキャンすることをサポートします。
- 注:行が大きい場合、特にテーブル内の他の列が結果セットに定期的に含まれている場合、これにより行のシリアルセットを選択する際に速度が向上する可能性があります。
- その場合、参照整合性のために主キーを使用して、他のテーブルの行を制約する外部キーとして必要な値を提供できます。PKは小さいため、FKは参照されるテーブルのサイズに対する小さなヒットです。
- ただし、クラスター化インデックスを持つテーブルで作成されたインデックスには、このテーブルで作成した他のインデックスのすべてのクラスター列が含まれることに注意してください。広いクラスター化インデックスは、そのテーブルのすべての非クラスター化インデックスのサイズを拡張します。
主キーのみをクラスター化インデックスにする必要がありますか?
小さな主キー(INTまたはBIGINT)があり、それがクラスター化インデックスである場合、クラスター列のオーバーヘッドは比較的小さくなります。この場合のクラスター化された主キーは、このテーブルのすべてのインデックスにも存在しますが、上記のワイドクラスターよりも安い価格です。
この主キークラスター化インデックスは通常、多数の行を連続して選択するための簡単なパスを直接提供しません。
クラスター化された主キーを作成したので、クラスター化インデックスに含める予定だった他の列についてはどうでしょうか?
必要に応じて、一意の(または非一意の)インデックスを作成し、列C1、C2、C3、C4、C5の幅広い検索条件にインデックスを付けます。この「模倣クラスター化」インデックスの値は、これらの5つの列の高速検索パスとして機能します。インデックス化されていない列が1つまたは2つあり、それらも定期的に選択されている場合、でインデックスに含めることができます INCLUDE (Doctor_Name, Diagnosis_Synopsis)
。
単純なクラスター化インデックスと主キーは有用であると思いますが、それらをテーブルで使用するかデータベースで使用するかを考える十分な理由があります。
クラスター化インデックスが必要ですか?
インデックス(ユニークインデックスと非ユニークインデックス)を作成し、クラスター化インデックスであるというオーバーヘッドなしで主キーを定義すると、より狭いインデックスがクエリに必要なものを提供する場合があります。
クラスター化インデックスと主キーにはいくつかの便利な動作がありますが、最も重要なのは実際にインデックスであることに注意してください。アプリケーションの現実を考慮して、インデックス戦略を設計します。おそらく、OneBigTable
ほとんどのテーブルで使用しているものとは異なるインデックス作成戦略が必要です。
クラスタ化インデックスがない場合、データは行識別子(RID)を含むヒープとして保存されますが、これはまったく適切な検索メカニズムではありません。ただし、前述のように、一意のインデックスと一意でないインデックスを作成して、クエリを処理できます。
これで、ヒープを検討することができます。
ヒープとインデックス: https : //msdn.microsoft.com/en-us/library/hh213609.aspx
- テーブルがヒープとして格納される場合、個々の行は、ファイル番号、データページ番号、およびページ上のスロットで構成される行識別子(RID)への参照によって識別されます。行IDは小さくて効率的な構造です。(ただし、インデックスではありません。)
- データが常に非クラスター化インデックスを介してアクセスされ、RIDがクラスター化インデックスキーよりも小さい場合、データアーキテクトはヒープを使用することがあります。
ただし、ビッグデータセットに「ホットスポット」がある場合は、別の種類のインデックスを調べることもできます。
フィルター選択されたインデックス: https : //msdn.microsoft.com/en-us/library/cc280372.aspx
適切に設計されたフィルター選択されたインデックスは、フルテーブルの非クラスター化インデックスよりも小さく、フィルターされた統計を持っているため、クエリのパフォーマンスと実行計画の品質が向上します。フィルタリングされた統計は、フィルタリングされたインデックスの行のみをカバーするため、フルテーブル統計よりも正確です。
フィルター選択されたインデックスには、フィルター選択されたインデックスへのリンクで概説されている多くの制限があります。
ただし、主キーとクラスター化インデックスを完全にスキップする可能性について考えている場合は、以下にリンクされているMarkus Winandの投稿を読んでください。彼は、いくつかのコードサンプルを使用して、これらの機能の使用を控えるのが良いアイデアであることを示唆する理由を示しています。
http://use-the-index-luke.com/blog/2014-01/unreasonable-defaults-primary-key-clustering-key
しかし最終的には、アプリケーションを理解し、実行中のジョブに合わせてコード、テーブル、インデックスなどを設計することに戻ります。