私はDBに対する経験が限られており、DBをアプリケーションプログラマーとしてしか使用していません。 Clustered
とNon clustered indexes
について知りたいのですが。グーグルで見つけたものは次のとおりです。
クラスタ化インデックスは、テーブル内のレコードが物理的に格納される方法を並べ替える特別な種類のインデックスです。したがって、テーブルは1つのクラスタ化インデックスのみを持つことができます。クラスタ化インデックスのリーフノードには、データページが含まれています。ノンクラスタード・インデックスは、インデックスの論理的順序がディスク上のローの物理的な格納順序と一致しない特殊なタイプのインデックスです。ノンクラスタードインデックスのリーフノードは、データページで構成されていません。代わりに、リーフノードにインデックス行が含まれています。
SOで見つけたものは クラスタ化インデックスと非クラスタ化インデックスの違いは何ですか? です。
誰かが平易な英語でこれを説明できますか?
クラスタ化インデックスでは、行はインデックスと同じ順序で物理的にディスクに格納されます。したがって、クラスタ化インデックスは1つだけ存在できます。
非クラスタ化インデックスでは、物理行へのポインタを持つ2番目のリストがあります。多くの非クラスタ化インデックスを作成できますが、新しいインデックスを作成するたびに新しいレコードを書き込むのにかかる時間が長くなります。
すべての列を取り戻す場合は、通常、クラスタード・インデックスから読み取る方が速いです。最初にインデックスに移動してからテーブルに移動する必要はありません。
データを並べ替える必要がある場合は、クラスタ化インデックスを持つテーブルへの書き込みが遅くなる可能性があります。
クラスタ化インデックスとは、近い値を実際には互いに近い値でディスクに格納するようにデータベースに指示していることを意味します。これには、ある範囲のクラスタ化インデックス値に分類されるレコードの高速スキャン/検索という利点があります。
たとえば、CustomerとOrderという2つのテーブルがあります。
Customer
----------
ID
Name
Address
Order
----------
ID
CustomerID
Price
ある特定の顧客のすべての注文をすばやく取得したい場合は、Orderテーブルの "CustomerID"列にクラスター化インデックスを作成します。このようにして、同じCustomerIDを持つレコードは、物理的にディスク上に物理的に近接して格納され(クラスタ化)、検索が高速化されます。
P.S CustomerIDのインデックスは明らかに一意ではないので、インデックスを "一意化"するために2番目のフィールドを追加するか、データベースに処理させる必要がありますが、これは別の話です。
複数のインデックスについてテーブルごとに1つのクラスタ化インデックスしか持てません。これは、データの物理的な配置方法を定義するためです。あなたが例えたいのなら、たくさんのテーブルがある大きな部屋を想像してください。これらのテーブルを配置して複数の行を形成することも、それらをまとめて大きな会議用テーブルを形成することもできますが、同時に両方向に使用することはできません。テーブルは他のインデックスを持つことができます、そしてそれらはそれから順番に実際のデータを見つけるべき場所を言うでしょうそれからクラスタ化インデックスのエントリを指します。
SQL Serverの行指向ストレージでは、クラスター化インデックスと非クラスター化インデックスの両方がBツリーとして編成されます。
( 画像ソース )
クラスター化インデックスと非クラスター化インデックスの主な違いは、クラスター化インデックスのリーフレベルisテーブルです。これには2つの意味があります。
非クラスター化インデックスは、INCLUDE
句(SQL Server 2005以降)を使用してすべての非キー列を明示的に含めることによりポイント1を実行できますが、セカンダリ表現であり、常にデータの別のコピー(テーブル自体)があります。
CREATE TABLE T
(
A INT,
B INT,
C INT,
D INT
)
CREATE UNIQUE CLUSTERED INDEX ci ON T(A,B)
CREATE UNIQUE NONCLUSTERED INDEX nci ON T(A,B) INCLUDE (C,D)
上記の2つのインデックスはほぼ同じです。キー列の値を含む上位レベルのインデックスページA,B
と、A,B,C,D
を含むリーフレベルページ
データ行自体は1つの順序でのみソートできるため、テーブルごとにクラスター化インデックスは1つしか存在できません。
SQL Serverオンラインブックからの上記の引用は、多くの混乱を引き起こします
私の意見では、はるかに良い言い回しになるでしょう。
クラスター化インデックスのリーフレベル行areはテーブル行であるため、テーブルごとにクラスター化インデックスは1つしか存在できません。
書籍のオンライン見積もりは間違っていませんが、非クラスター化インデックスとクラスター化インデックスの両方の「ソート」は物理的ではなく論理的であることを明確にする必要があります。リンクされたリストに従ってリーフレベルでページを読み取り、ページの行をスロット配列順に読み取った場合、インデックス行はソート順に読み取られますが、物理的にページがソートされない場合があります。クラスター化インデックスでは、行は常にインデックスと同じ順序でディスクに物理的に格納されるという一般的な信念keyはfalseです。
これはばかげた実装になります。たとえば、4 GBのテーブルの中央に行が挿入された場合、SQL Serverはnotにファイルに2 GBのデータをコピーして、新しく挿入された行のためのスペースを確保する必要があります。
代わりに、ページ分割が発生します。クラスター化インデックスと非クラスター化インデックスの両方のリーフレベルの各ページには、論理キー順で次のページと前のページのアドレス(File:Page
)があります。これらのページは、連続している必要も、キーの順序である必要もありません。
例えばリンクされたページチェーンは1:2000 <-> 1:157 <-> 1:7053
になります
ページ分割が発生すると、ファイルグループ内の任意の場所(小さなテーブルの場合は混合エクステント、そのオブジェクトに属する空ではない均一エクステント、または新しく割り当てられた均一エクステント)から新しいページが割り当てられます。ファイルグループに複数のファイルが含まれている場合、これは同じファイルにない場合もあります。
論理的な順序と連続性が理想的な物理バージョンと異なる度合いは、論理的な断片化の度合いです。
単一のファイルで新しく作成されたデータベースで、次を実行しました。
CREATE TABLE T
(
X TINYINT NOT NULL,
Y CHAR(3000) NULL
);
CREATE CLUSTERED INDEX ix
ON T(X);
GO
--Insert 100 rows with values 1 - 100 in random order
DECLARE @C1 AS CURSOR,
@X AS INT
SET @C1 = CURSOR FAST_FORWARD
FOR SELECT number
FROM master..spt_values
WHERE type = 'P'
AND number BETWEEN 1 AND 100
ORDER BY CRYPT_GEN_RANDOM(4)
OPEN @C1;
FETCH NEXT FROM @C1 INTO @X;
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO T (X)
VALUES (@X);
FETCH NEXT FROM @C1 INTO @X;
END
次に、ページレイアウトをチェックしました
SELECT page_id,
X,
geometry::Point(page_id, X, 0).STBuffer(1)
FROM T
CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
ORDER BY page_id
結果はいたるところにありました。キー順の最初の行(値1-下の矢印で強調表示)は、ほぼ最後の物理ページにありました。
断片化は、インデックスを再構築または再編成して、論理的順序と物理的順序の相関を高めることにより、削減または削除できます。
走った後
ALTER INDEX ix ON T REBUILD;
私は次のものを手に入れました
テーブルにクラスター化インデックスがない場合は、ヒープと呼ばれます。
非クラスター化インデックスは、ヒープまたはクラスター化インデックスのいずれかに構築できます。これらには常に、ベーステーブルに戻る行ロケーターが含まれています。ヒープの場合、これは物理行識別子(rid)であり、3つのコンポーネント(ファイル:ページ:スロット)で構成されます。クラスター化インデックスの場合、行ロケーターは論理的です(クラスター化インデックスキー)。
後者の場合、非クラスター化インデックスにすでにNCIキー列またはINCLUDE
- d列としてCIキー列が自然に含まれている場合、何も追加されません。それ以外の場合、欠落しているCIキー列は、NCIにサイレントに追加されます。
SQL Serverは、キー列が両方のタイプのインデックスに対して一意であることを常に保証します。ただし、一意として宣言されていないインデックスにこれが適用されるメカニズムは、2つのインデックスタイプ間で異なります。
クラスター化インデックスは、既存の行を複製するキー値を持つ行にuniquifier
追加されます。これは単なる昇順の整数です。
一意のSQL Serverとして宣言されていない非クラスター化インデックスの場合、行ロケーターを非クラスター化インデックスキーにサイレントに追加します。これは、実際に重複している行だけでなく、すべての行に適用されます。
クラスター化された命名法と非クラスター化された命名法は、列ストアインデックスにも使用されます。論文 SQL Server列ストアの拡張 状態
列ストアデータは実際にはどのキーでも「クラスター化」されていませんが、プライマリインデックスをクラスター化インデックスとして参照する従来のSQL Serverの規則を保持することにしました。
私はこれが非常に古い質問であることを認識しています、しかし私は私が上記の良い答えを説明するのを助けるために類推を提供するであろうと思いました。
公立図書館に足を踏み入れると、本はすべて特定の順序で配置されていることがわかります(ほとんどの場合、Dewey Decimal System(DDS))。これは、書籍の "クラスタ化インデックス" に対応します。必要な本のDDS番号が005.7565 F736s
である場合は、まず、001-099
というラベルの付いた本棚の行を探します。最終的には、005.7450 - 005.7600
というラベルの付いた特定のシェルフにドリルダウンし、指定したDDS#の本が見つかるまでスキャンします。その時点で あなたはあなたの本を見つけました。
あなたの本のDDS#が記憶されていないのに図書館に来なかったのなら、あなたはあなたを助けるために2番目の索引が必要になるでしょう。昔は図書館の正面に「カードカタログ」として知られている素晴らしい引き出し局がありました。それぞれの本に1枚ずつ、アルファベット順に(おそらくタイトル順に)ソートされた、3×5枚のカードが何千枚もありました。これは "非クラスタ化インデックス" に対応します。これらのカードカタログは階層構造で編成されていたので、各引き出しはそれが含んでいたカードの範囲でラベル付けされていた(例えばKa - Kl
、すなわち「中間ノード」)。もう一度、あなたはあなたの本が見つかるまでドリルインするでしょう、しかし this ケースでは、あなたがそれを見つけたら(すなわち、 "リーフノード")、あなたは本自体を持っておらず、ただカードを持っています index number(DDS#)を使って、実際の本をクラスタ化インデックスで見つけることができます。
もちろん、司書がすべてのカードをコピーして別のカードカタログに別の順序で並べ替えることを妨げるものは何もありません。 (通常、カタログは少なくとも2つあり、1つは著者名で、もう1つはタイトルでソートされています。)原則として、これらの「非クラスタ化」インデックスを必要なだけ作成できます。
クラスタ化インデックスと非クラスタ化インデックスのいくつかの特性を以下に示します。
create Index index_name(col1, col2, col.....)
です。非常に単純で非技術的な経験則は、通常、主キーにクラスタ化インデックスが使用され(または少なくとも一意の列)、その他の状況(おそらく外部キー)には非クラスタ化インデックスが使用されることです。 。実際、SQL Serverはデフォルトで主キーカラムにクラスタ化インデックスを作成します。あなたが学んだように、クラスタード・インデックスはデータがディスク上で物理的にソートされる方法に関連しています。
クラスタ化インデックス
クラスタ化インデックスは、テーブル内のDATAの物理的な順序を決定します。このため、テーブルには1つのクラスタ化インデックスしかありません。
"dictionary"のように他のインデックスは必要ありません。単語に従ったインデックスです。
ノンクラスタードインデックス
非クラスタ化インデックスはBookのインデックスに似ています。データは1か所に格納されます。インデックスは別の場所に格納され、インデックスはデータの格納場所へのポインタを持ちます。このため、テーブルには複数のノンクラスタードインデックスがあります。
「化学書」のように、章の場所を指す別の索引があり、「終了」には、共通のWORDSの場所を指す別の索引があります
クラスタ化インデックス
クラスタード・インデックスは、キー値に基づいてテーブルまたはビュー内のデータ行をソートして格納します。これらは索引定義に含まれる列です。データ行自体は1つの順序でのみ並べ替えることができるため、テーブルごとに1つのクラスタ化インデックスしか存在できません。
テーブル内のデータローがソート順に格納されるのは、テーブルにクラスタ化インデックスが含まれている場合だけです。テーブルにクラスタ化インデックスがある場合、そのテーブルはクラスタ化テーブルと呼ばれます。テーブルにクラスタ化インデックスがない場合、そのデータローはヒープと呼ばれる順序付けられていない構造に格納されます。
非クラスタ化
非クラスタ化インデックスは、データ行とは別の構造を持ちます。ノンクラスタード・インデックスにはノンクラスタード・インデックスのキー値が含まれ、各キー値エントリにはキー値を含むデータ行へのポインタがあります。非クラスタ化インデックス内のインデックス行からデータ行へのポインタは、行ロケータと呼ばれます。行ロケータの構造は、データページがヒープに格納されているか、クラスタ化されたテーブルに格納されているかによって異なります。ヒープの場合、行ロケーターはその行へのポインターです。クラスタードテーブルの場合、行ロケーターはクラスタードインデックスキーです。
ノンクラスタード・インデックスのリーフ・レベルにノンキー・カラムを追加して、既存のインデックスのキー制限を回避し、完全にカバーされたインデックス付きのクエリを実行できます。詳細については、「インクルード列を含むインデックスを作成する」を参照してください。インデックスキーの制限の詳細については、SQL Serverの最大容量の仕様を参照してください。
クラスタ化インデックス: テーブルにクラスタ化インデックスが存在しない場合、主キー制約は自動的にクラスタ化インデックスを作成します。クラスタ化インデックスの実際のデータは、インデックスのリーフレベルで格納できます。
非クラスタ化インデックス: 非クラスタ化インデックスの実際のデータは、リーフノードで直接検出されません。実際のデータを指す行ロケータの値しかないため、検出するための追加手順が必要です。非クラスタ化インデックスをクラスタ化インデックスとして並べ替えることはできません。テーブルごとに複数の非クラスタ化インデックスが存在する可能性があります。実際には、使用しているSQL Serverのバージョンによって異なります。基本的にSQL Server 2005では、249の非クラスタ化インデックスが許可され、2008、2016のような上記のバージョンでは、テーブルあたり999の非クラスタ化インデックスが許可されます。
"クラスタリングインデックス"についての教科書の定義を提供しよう。それは データベースシステム:The Complete Book :から15.6.1からとられる。
クラスタリングインデックス についても言えます。これは、このインデックスの検索キーの値が固定されているすべてのタプルが、それらを保持できるのと同じくらい少ないブロックに現れるようなものです。
定義を理解するために、教科書で提供されている例15.10を見てみましょう。
属性
a
でソートされ、その順序で格納され、ブロックにパックされている関係R(a,b)
は、確実にクラスター化されています。a
のインデックスはクラスタリングインデックスです。これは、指定されたa
-値a1に対して、a
の値を持つすべてのタプルが連続しているためです。そのため、それらはブロックに詰め込まれているように見えますが、図15.14に示されているように、おそらくa
_value a1を含む最初と最後のブロックを除きます。ただし、固定のb
-値を持つタプルは、a
とb
の値が非常に密接に相関していない限り、ファイル全体に分散されるため、bのインデックスはクラスタリングされる可能性が低いです。
この定義では、データブロックがディスク上で連続している必要はないことに注意してください。それは、検索キーを持つタプルができるだけ少ないデータブロックにパックされていると言うだけです。
関連する概念は クラスター化関係 です。そのタプルが、それらのタプルを保持することができるのと同じくらい少ないブロックにパックされている場合、関係は「クラスタ化」されます。言い換えれば、ディスクブロックの観点から、それが異なるリレーションからのタプルを含む場合、それらのリレーションをクラスタ化することはできません(すなわち、そのリレーションのタプルを他のディスクブロックからタプルは現在のディスクブロックの関係に属していません。明らかに、上の例のR(a,b)
はクラスタ化されています。
2つの概念を結び付けるために、クラスタ化リレーションはクラスタリングインデックスと非クラスタリングインデックスを持つことができます。ただし、非クラスタ化リレーションの場合、インデックスがリレーションの主キーの上に構築されていない限り、クラスタリングインデックスは使用できません。
Wordとしての「クラスタ」は、データベースストレージ側のすべての抽象化レベル(3つの抽象化レベル:タプル、ブロック、ファイル)にわたってスパムされています。ファイル(ブロックのグループ(1つまたは複数のディスクブロック)の抽象化)に1つの関係からのタプルまたは異なる関係からのタプルが含まれているかどうかを記述する「 clustered file 」と呼ばれる概念。ファイルレベルであるため、クラスタリングインデックスの概念とは関係ありません。
しかし、いくつかの 教材 は、クラスタ化されたファイルの定義に基づいてクラスタリングインデックスを定義するのが好きです。これら2種類の定義は、それらがデータディスクブロックまたはファイルの観点からクラスタ化関係を定義するかどうかにかかわらず、クラスタ化関係レベルで同じです。この段落のリンクから、
ファイル上の属性Aのインデックスは、次の場合にクラスタリングインデックスになります。属性値A = aのすべてのタプルがデータファイルに順次(=連続して)格納されている
タプルを連続して格納することは、「タプルは、それらのタプルを保持できる最大数のブロックにパックされる」と言うのと同じです(ファイルに関する話とディスクに関する話とで多少の違いはあります)。これは、Tupleを連続して格納することが、「それらのタプルを保持できる最大数のブロックにパックされる」ことを実現するための方法だからです。