clustered
とnon-clustered index
の違いは何ですか?
クラスタ化インデックス
非クラスタ化インデックス
どちらのタイプのインデックスでも、インデックスを使用するフィールドを持つデータを選択するとパフォーマンスが向上しますが、更新操作と挿入操作は遅くなります。
挿入と更新の速度が遅いため、通常は増分的なフィールド、つまりIdまたはTimestampにはクラスタ化インデックスを設定する必要があります。
SQL Serverは通常、選択性が95%を超える場合にのみインデックスを使用します。
クラスタ化インデックスは、ディスク上のデータを物理的に並べます。これは、インデックスに余分なデータが必要ないことを意味しますが、クラスタ化インデックスは1つしか存在できません(明らかに)。クラスタード・インデックスを使用してデータにアクセスするのが最速です。
他のすべてのインデックスはクラスタ化されていない必要があります。非クラスタ化インデックスには、実際のデータ行へのポインタ(存在する場合は、クラスタ化インデックスへのポインタ)と共に並べられたインデックス付きカラムのデータの複製があります。つまり、非クラスタ化インデックスを介してデータにアクセスするには、追加の間接層を通過する必要があります。ただし、インデックス付きの列で利用可能なデータのみを選択した場合は、複製されたインデックスデータから直接データを取り戻すことができます(必要な列のみをSELECTし、*を使用しないことをお勧めします)
クラスタ化インデックスはテーブルに物理的に格納されます。これは、それらが最速であり、テーブルごとに1つのクラスタ化インデックスしか持てないことを意味します。
非クラスタ化インデックスは別々に格納され、必要なだけいくつでも持つことができます。
最善の選択肢は、最も使用頻度の高い一意の列(通常はPK)にクラスター化インデックスを設定することです。非常に説得力のある理由 - 単一のものを考えることができない場合を除き、あなたは常にあなたのテーブルに適切に選択されたクラスタ化インデックスを持つべきです。
これらの違いとは別に、テーブルがクラスタ化されていないとき(テーブルにクラスタ化インデックスがないとき)のデータファイルは順不同で、データ構造としてHeapデータ構造を使用することを知っておく必要があります。
クラスタ化とは、基本的に、データがテーブル内でその物理的順序にあることを意味します。これが、テーブルごとに1つしか持てない理由です。
クラスタ化されていないとは、論理的な順序が「唯一の」ことを意味します。
長所:
クラスタ化インデックスは範囲に対して非常に有効です(例えば、my_keyから@minと@maxの間のmy_tableから*を選択します)。
場合によっては、orderby文を使用するとDBMSがソートの作業をする必要がなくなります。
短所:
新しいキーが順番に並んでいない場合は、レコードが挿入されるときにレコードの物理レイアウトを変更する必要があるため、クラスタ化インデックスは挿入を遅くする可能性があります。
クラスタ化インデックスは実際にはレコードがディスクに物理的に格納されている順序を記述しているので、1つしか持てない理由です。
ノンクラスタードインデックスは、ディスク上の物理的な順序と一致しない論理的な順序を定義します。
クラスタード・インデックスは、本質的にはインデックス付きカラムのデータのソートされたコピーです。
クラスタ化インデックスの主な利点は、クエリ(seek)がインデックス内のデータを見つけるときに、そのデータを取得するために追加のIOが不要になることです。
特に頻繁に更新されるテーブルでクラスタ化インデックスを管理することによるオーバーヘッドは、パフォーマンスの低下を招く可能性があるため、非クラスタ化インデックスを作成することをお勧めします。
索引付きデータベースには、2つの部分があります。任意の順序で配置された一連の物理レコードと、何らかの基準でソートされた結果を得るためにレコードを読み取る順序を識別する一連の索引です。物理的な配置とインデックスの間に相関がない場合は、順番にすべてのレコードを読み取るには、多数の独立した単一レコード読み取り操作を行う必要があります。データベースは、2つの連続していないレコードを読み取るのにかかる時間よりも短時間で何十もの連続したレコードを読み取ることができるため、インデックス内で連続しているレコードも連続してディスクに格納されるとパフォーマンスが向上します。インデックスがクラスタ化されるように指定すると、データベースはインデックス内で連続するレコードのグループがディスク上で連続するように、物事を調整するための何らかの努力をすることになります(データベースによって異なります)。
たとえば、空のクラスタ化されていないデータベースから始めて、ランダムな順序で10,000レコードを追加する場合、レコードは追加された順に最後に追加される可能性があります。データベースをインデックス順に読み取るには、1レコードの1レコード読み取りが必要です。ただし、クラスタ化データベースを使用する場合、システムは各レコードを追加するときに、前のレコードが単独で格納されているかどうかを確認することがあります。そうであるとわかった場合は、データベースの最後に新しいレコードを使用してそのレコードを書き込む可能性があります。その後、移動したレコードが存在していたスロットの前の物理レコードを調べ、それに続くレコードがそれ自体で格納されているかどうかを確認できます。それが事実であるとわかった場合は、そのレコードをその場所に移動できます。この種のアプローチを使用すると、多くのレコードがペアになってグループ化されるため、順次読み取り速度がほぼ倍増する可能性があります。
実際には、クラスタ化データベースはこれよりも高度なアルゴリズムを使用します。ただし、注意すべき重要な点は、データベースの更新に必要な時間とデータベースの順次読み取りに必要な時間との間にはトレードオフがあることです。クラスタ化されたデータベースを維持すると、ソート順序に影響を与えるような方法でレコードを追加、削除、または更新するために必要な作業量が大幅に増加します。データベースが更新されるよりもはるかに頻繁に順次読み取られる場合、クラスタリングは大きな勝利になる可能性があります。頻繁に更新されますが、順番に読み出されることはめったにない場合、特にアイテムがデータベースに追加される順序がクラスタ化インデックスに関するソート順とは無関係である場合、クラスタ化はパフォーマンスを大きく低下させる可能性があります。
// MSDNからコピーした、非クラスタ化インデックスの2番目のポイントは、他の回答では明確に述べられていません。
クラスタ化
非クラスタ化