3

私は最近、方法clustered indexnon-clustered index仕組みについて読んでいます。簡単な言葉での私の理解(間違っている場合は修正してください):

clustered裏打ちされnon-clustered indexたデータ構造B-Tree

Clustered Index: インデックス列 (またはキー) に基づいてデータを物理的に並べ替えます。clustered Indexごとに 1 つだけ持つことができますtableindexテーブルの作成時にno が指定された場合、SQLサーバーは自動的に に を作成しclustered Indexますprimary key column

Q1 : データはインデックスに基づいて物理的にソートされているため、ここに余分なスペースは必要ありません。これは正しいです?作成したインデックスを削除するとどうなりますか?

Non-clustered Index: ではnon-clustered indexesleaf-nodeツリーの には、列の値と、データベース内の実際の行へのポインター (行ロケーター) が含まれています。non-clustered index tableこれを物理的にディスクに格納するために余分なスペースが必要です。ただし、1本は数に限りません。non-clustered Indexes.

Q2 : 非クラスター化インデックス列に対するクエリでは、並べ替えられたデータが得られないということですか?

Q3 : リーフ ノードのポインタを使用して実際の行データを見つけるために、ここに関連付けられた追加のルックアップがあります。クラスター化インデックスと比較した場合、これはどの程度のパフォーマンスの違いになりますか?

演習:

Employee テーブルを考えてみましょう:

CREATE TABLE Employee
(
PersonID int PRIMARY KEY,
Name varchar(255),
age int,
salary int
); 

ここで、employee テーブルを作成しました (employee のデフォルトのクラスター化インデックスが作成されます)。

このテーブルに対する 2 つの頻繁なクエリは、年齢列と給与列でのみ発生します。簡単にするために、テーブルが頻繁に更新されないと仮定しましょう

例えば:

select * from employee where age > XXX;

select * from employee where salary > XXXX and salary < YYYY;

Q4 : インデックスを構築する最良の方法は何ですか。これらの両方の列に対するクエリのパフォーマンスが同様になります。age 列の age クエリにクラスター化インデックスがある場合、age 列のクエリは高速になりますが、salary 列よりも遅くなります。

Q5 : 関連するメモとして、一意の制約を持つ列にインデックス (クラスター化されたインデックスとクラスター化されていないインデックスの両方) を作成する必要があることを繰り返し見てきました。何故ですか?これを怠るとどうなりますか?

どうもありがとうございました。私が読んだ投稿は次のとおりです。

http://javarevisited.blogspot.com/2013/08/difference-between-clustered-index-and-nonclustered-index-sql-server-database.html

http://msdn.microsoft.com/en-us/library/ms190457.aspx

クラスター化されたものとクラスター化されていないもの

クラスター化インデックスと非クラスター化インデックスの実際の意味は何ですか?

クラスター化インデックスと非クラスター化インデックスの違いは何ですか?

データベースのインデックス作成はどのように機能しますか?

4

2 に答える 2

5

Microsoft SQL Server の内部についてはわかりませんが、質問にタグを付けた MySQL についてはお答えできます。詳細は、他の実装では異なる場合があります。

Q1. そうです、クラスター化インデックスに余分なスペースは必要ありません。

クラスター化インデックスを削除するとどうなりますか? MySQL の InnoDB エンジンは、常に主キー (または最初の null 以外の一意のキー) をクラスター化インデックスとして使用します。主キーなしでテーブルを定義するか、既存のテーブルの主キーを削除すると、InnoDB はクラスター化インデックスの内部人工キーを生成します。この内部キーには、それを参照するための論理列がありません。

Q2. 非クラスター化インデックスを使用するクエリによって返される行の順序は保証されません。実際には、行がアクセスされた順序です。行を特定の順序で返す必要がある場合ORDER BYは、クエリで を使用する必要があります。オプティマイザーが、目的の順序が行にアクセスする順序 (クラスター化インデックスまたは非クラスター化インデックスのいずれによるインデックス順) と同じであると推測できる場合、並べ替え手順をスキップできます。

Q3. InnoDB の非クラスター化インデックスには、インデックスのリーフに対応する行へのポインターがなく、主キーの値があります。したがって、非クラスター化インデックスでの参照は、実際には 2 つの B ツリー検索であり、最初に非クラスター化インデックスのリーフを検索し、次にクラスター化インデックスで 2 回目の検索を行います。

これは、単一の B ツリー検索の 2 倍のコスト (多かれ少なかれ) であるため、 InnoDB にはAdaptive Hash Indexと呼ばれる追加機能があります。頻繁に検索される値は AHI にキャッシュされ、次にクエリがキャッシュされた値を検索するときに、O(1) ルックアップを実行できます。AHI キャッシュでは、クラスター化インデックスのリーフを直接指すポインターが検出されるため、両方のB ツリー検索が省略される場合があります。

これにより全体のパフォーマンスがどの程度向上するかは、以前に検索された同じ値を検索する頻度によって異なります。私の経験では、ハッシュ検索と非ハッシュ検索の比率は約 1:2 であるのが一般的です。

Q4. 最適化が必要なクエリを提供するインデックスを構築します。通常、クラスター化されたインデックスは主キーまたは一意のキーであり、少なくとも InnoDB の場合はこれが必要です。一意である可能性も、一意である可能性ageもありません。salary

私のプレゼンテーションHow to Design Indexes, Really を気に入っていただけると思います。

Q5. ユニーク制約を宣言すると、 InnoDB は自動的にインデックスを作成します。インデックスが存在しないと、制約を設定できません。インデックスがない場合、値を挿入するときにエンジンはどのようにして一意性を保証するのでしょうか? その列に重複する値がないか、テーブル全体を検索する必要があります。インデックスは、一意のチェックをより効率的にするのに役立ちます。

于 2014-09-12T19:48:35.553 に答える
3

SQL サーバーの場合

Q1クラスター化インデックスが一意でない場合にのみ、追加のスペースが必要です。SQL Server は、一意でないクラスター化インデックスに 4 バイトの一意識別子を内部的に追加します。これは、非クラスター化インデックスでクラスター キーを行 ID として使用するためです。

Q2非クラスタ化インデックスを順番に読み込めます。これは、順序を指定するクエリに役立つ場合があります。また、マージ結合が魅力的になる場合もあります。範囲クエリ (x < col および y > col) にも役立ちます。

第 3 四半期SQL Server は、非クラスター化インデックスを使用する場合、追加の "ブックマーク ルックアップ" を実行します。ただし、これは、インデックスにない列が必要な場合のみです。includeまた、インデックスのリーフ レベルで列を追加できることにも注意してください。追加のルックアップなしでインデックスを使用できる場合、それはカバリング インデックスと呼ばれます。

ブックマーク ルックアップが必要な場合は、クラスター化インデックス全体をスキャンする方が高速になるまで、高い割合の行を必要としません。レベルは、行のサイズ、キーのサイズなどによって異なります。ただし、行の 5% が通常のカットオフです。

Q4アプリケーションで最も重要なことは、これらの両方のクエリを可能な限り高速にすることである場合、両方にカバリング インデックスを作成できます。

create index IX_1 on employee (age) include (name, salary);
create index IX_2 on employee (salary) include (name, age);

非クラスター化インデックスには行ポインターとしてクラスター キーがあるため、特にクラスター キーを含める必要はありません。

Q5これは、一意性により、非クラスタ キーよりもクラスタ キーの方が重要です。ただし、実際の問題は、インデックスがクエリに対して選択的であるかどうかです。値のインデックスを想像してくださいbit。データの分布が非常に歪んでいない限り、そのようなインデックスは何にも使用されません。


一意識別子に関する詳細情報。あなたと、年齢に関する一意ではないクラスター化インデックスと、給与に関する非クラスター化インデックスを想像してみてください。次の行があるとします。

age | salary | uniqifier
20  | 1000   | 1
20  | 2000   | 2

次に、給与インデックスは次のように行を見つけます

1000 -> 20, 1
2000 -> 20, 2

クエリを実行select * from employee where salary = 1000し、オプティマイザーが給与インデックスの使用を選択したとします。次に、インデックス ルックアップからペア (20, 1) を見つけ、メイン データでこの値をルックアップします。

于 2014-09-12T20:05:00.373 に答える