Stackoverflowでこの投稿に出くわしました。最初の答えは、クラスター化インデックスにはテーブルのすべてのデータがあり、非クラスター化インデックスには列+クラスター化インデックスの場所、またはヒープ上にある場合は行(クラスター化インデックスのないテーブル)のみがあるというようなものです。非クラスター化インデックスはどのようにしてクラスター化インデックスの場所を知ることができますか?これには、Bツリー内のノードとしてソートされた列値のみが含まれ、各ノードは、列がそのノード値を持つ行にピン留めされます。
2 に答える
SQL Serverについて話していると仮定し、テーブルにクラスター化インデックスがあると仮定します(当然のことです)。
次に、非クラスター化インデックスには、CREATE INDEX
ステートメントで定義した列と、クラスター化インデックス (存在する場合) を構成する列があります。
そのクラスタリング キーの値は、実際のデータが配置されている場所への「ポインター」です。
クエリ エグゼキューターが非クラスター化インデックスをシークして値を探し、一致するものを見つけた場合、
その値だけを気にするか、その値を取得するだけです
または、非クラスター化インデックスにも (リーフ レベルのページに) いくつかの列が含まれている可能性があり、それらを使用してクエリが満たされる (要求されたすべての列が存在する) ため、要求した値が返されます。
または、必要な値がすべて非クラスター化インデックスのリーフ レベル ページにあるわけではなく (これは、
SELECT *
常に行う場合に特に当てはまります)、クエリ実行者は非クラスター化インデックスからクラスター化キー値を取得し、元のページに戻る必要があります。クラスタリング インデックス、キー ルックアップと呼ばれるものを実行し、クラスタリング インデックスをシークし、完全な行が格納されている関連データ ページを見つけます ->これで、クエリ エグゼキュータは要求した値を返すことができます
わかりやすい説明については、こちらのブログ記事を参照してください。それは言います:
非クラスター化インデックス:
....
2.b. テーブルにクラスター化インデックスがある場合、またはインデックスがインデックス付きビューにある場合、行ロケーターは行のクラスター化インデックス キーです。SQL Server は、NonClustered インデックスの Leaf 行に格納されている Clustered index Key を使用して Clustered インデックスを検索することにより、データ行を取得します。
または、非クラスター化インデックスのリーフ レベル ページに格納されている "ブックマーク" について説明している、SQL Server インデックスに関するシリーズ全体のこのブログ投稿も参照してください。
このように想像するのはかなり簡単です:
たとえば、customer(id、name、age、address)などの顧客のテーブルがあります。このテーブルには、年齢に関するクラスター化されたインデックスがあります。これは、データがハードドライブ上の年齢で並べ替えられていることを意味します。これは、次のような範囲クエリを実行する場合に非常に役立ちます。
SELECT * FROM customer WHERE age > 18;
その後、数回のシーケンシャル読み取りでデータをハードドライブからフェッチできます。インデックスがクラスター化されていない場合は、一致する顧客タプルごとに1つのディスクアクセス(データのシークを含む)を行う必要があります。
たぶんあなたのアプリケーションのためにあなたはまたidによってユーザーにアクセスする必要があります。つまり、idに追加のインデックスがないと、ファイル全体を調べて特定のIDを見つける必要があります。これは、ファイルが年齢でソートされており、インデックスがないためです。これを回避するには、idに2番目のインデックスを作成します。これで、このインデックスでIDを検索できます。インデックスのリーフには、探している顧客が含まれており、ディスク上の(年齢別にクラスター化された)データ内のタプルが見つかった場所を指します。これにより、テーブル全体を読み取る必要がなく、必要なディスクアクセスがはるかに少なくなります(通常、インデックスルックアップ用に2 +タプルをフェッチするために1)。
編集:あなたが同じコラムについて話しているのを見ませんでした。私が想像できることの1つは、上記の理由で1つの列に対して1つのクラスター化インデックスを作成し、たとえば、この列と別の列の別の複合インデックスを作成することです。これは、インデックスのみのルックアップを実行する場合に役立ちます。ここでは、インデックスに必要なすべての属性があり、ページフェッチを実行する必要はありません。もう1つの理由は、範囲クエリ用にクラスター化されたB +インデックスを使用し、等式クエリ用にハッシュインデックスを使用することです。しかし、ここでのメリットはごくわずかだと思います。
これがお役に立てば幸いです。