1227

私はDBに触れる機会が限られており、アプリケーションプログラマーとしてDBを使用しただけです。Clusteredとについて知りたいNon clustered indexes。私はグーグルで検索しました、そして私が見つけたものは:

クラスタ化インデックスは、テーブル内のレコードが物理的に格納される方法を並べ替える特殊なタイプのインデックスです。したがって、テーブルに含めることができるクラスター化インデックスは1つだけです。クラスタ化されたインデックスのリーフノードには、データページが含まれています。非クラスター化インデックスは、インデックスの論理的な順序がディスク上の行の物理的に格納された順序と一致しない特殊なタイプのインデックスです。非クラスター化インデックスのリーフノードは、データページで構成されていません。代わりに、リーフノードにはインデックス行が含まれています。

SOで見つけたのは、クラスター化されたインデックスとクラスター化されていないインデックスの違いは何ですか?

誰かがこれを平易な英語で説明できますか?

4

12 に答える 12

1237

クラスタ化インデックスを使用すると、行はインデックスと同じ順序でディスクに物理的に格納されます。したがって、クラスター化されたインデックスは1つだけです。

非クラスター化インデックスには、物理​​行へのポインターを持つ2番目のリストがあります。クラスター化されていないインデックスを多数持つことができますが、新しいインデックスを作成するたびに、新しいレコードの書き込みにかかる時間が長くなります。

すべての列を取得したい場合は、通常、クラスター化インデックスから読み取る方が高速です。最初にインデックスに移動してからテーブルに移動する必要はありません。

データを再配置する必要がある場合は、クラスター化インデックスを使用したテーブルへの書き込みが遅くなる可能性があります。

于 2009-08-09T16:05:40.293 に答える
615

クラスタ化インデックスとは、実際に互いに近い値をディスクに格納するようにデータベースに指示していることを意味します。これには、クラスター化インデックス値のある範囲に分類されるレコードの迅速なスキャン/取得という利点があります。

たとえば、CustomerとOrderの2つのテーブルがあります。

Customer
----------
ID
Name
Address

Order
----------
ID
CustomerID
Price

特定の顧客のすべての注文をすばやく取得する場合は、Orderテーブルの「CustomerID」列にクラスター化インデックスを作成することをお勧めします。このようにして、同じCustomerIDを持つレコードは、物理的に互いに近くにディスク(クラスター化)に保存されるため、取得が高速化されます。

PS CustomerIDのインデックスは明らかに一意ではないため、インデックスを「一意化」するために2番目のフィールドを追加するか、データベースにそれを処理させる必要がありますが、それは別の話です。

複数のインデックスについて。データが物理的に配置される方法を定義するため、テーブルごとに1つのクラスター化インデックスのみを持つことができます。例えを望むなら、たくさんのテーブルがある大きな部屋を想像してみてください。これらのテーブルを配置して複数の行を形成することも、すべてをまとめて大きな会議テーブルを形成することもできますが、同時に両方の方法を使用することはできません。テーブルは他のインデックスを持つことができ、それらはクラスター化インデックスのエントリを指し、クラスター化インデックスは最終的に実際のデータの場所を示します。

于 2009-08-09T16:01:24.840 に答える
347

SQL Serverでは、クラスター化インデックスと非クラスター化インデックスの両方の行指向のストレージがBツリーとして編成されます。

ここに画像の説明を入力してください

画像ソース

クラスタ化インデックスと非クラスタ化インデックスの主な違いは、クラスタ化インデックスのリーフレベルがテーブルであるということです。これには2つの意味があります。

  1. クラスタ化インデックスリーフページの行には、テーブル内の(スパースではない)列ごとに何か(値または実際の値へのポインタ)が常に含まれています。
  2. クラスタ化インデックスは、テーブルのプライマリコピーです。

非クラスター化インデックスは、INCLUDE句(SQL Server 2005以降)を使用してすべての非キー列を明示的に含めることでポイント1を実行することもできますが、これらは2次表現であり、データの別のコピー(テーブル自体)が常に存在します。

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つのクラスター化インデックスしか存在できません。

オンラインのSQLServerブックからの上記の引用は、多くの混乱を引き起こします

私の意見では、それはとしてはるかに良い言い回しになるでしょう。

クラスタ化インデックスのリーフレベルの行はテーブルの行であるため、テーブルごとに1つのクラスタ化インデックスしか存在できません。

この本のオンライン引用は正しくありませんが、非クラスター化インデックスとクラスター化インデックスの両方の「ソート」は物理的ではなく論理的であることを明確にする必要があります。リンクリストに従ってリーフレベルでページを読み取り、スロット配列の順序でページの行を読み取ると、インデックス行がソートされた順序で読み取られますが、物理的にはページがソートされない場合があります。クラスタ化インデックスでは、行は常にインデックスキーがfalseであるのと同じ順序でディスクに物理的に格納されるという一般的な考えがあります。

これはばかげた実装になります。たとえば、行が4GBのテーブルの中央に挿入された場合、SQL Serverは、新しく挿入された行用のスペースを確保するために、ファイル内の2GBのデータをコピーする必要はありません。

代わりに、ページ分割が発生します。クラスタ化インデックスと非クラスタ化インデックスの両方のリーフレベルの各ページにはFile: Page、論理キー順に次のページと前のページのアドレス()があります。これらのページは、連続しているか、キー順になっている必要はありません。

たとえば、リンクされたページチェーンは1:2000 <-> 1:157 <-> 1:7053

ページ分割が発生すると、ファイルグループ内の任意の場所から新しいページが割り当てられます(混合エクステント、小さなテーブルの場合、またはそのオブジェクトに属する空でない均一エクステント、または新しく割り当てられた均一エクステントのいずれかから)。ファイルグループに複数のファイルが含まれている場合、これは同じファイルに含まれていない可能性があります。

論理的な順序と隣接性が理想的な物理バージョンとどの程度異なるかは、論理的な断片化の程度です。

1つのファイルで新しく作成されたデータベースで、次のように実行しました。

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つのコンポーネント(File:Page:Slot)で構成されます。クラスター化インデックスの場合、行ロケーターは論理的です(クラスター化インデックスキー)。

後者の場合、非クラスター化インデックスにNCIキー列またはINCLUDE-d列のいずれかとしてCIキー列がすでに自然に含まれている場合、何も追加されません。それ以外の場合、欠落しているCIキー列はサイレントにNCIに追加されます。

SQL Serverは、キー列が両方のタイプのインデックスに対して一意であることを常に確認します。ただし、一意として宣言されていないインデックスにこれが適用されるメカニズムは、2つのインデックスタイプ間で異なります。

クラスタ化インデックスはuniquifier、既存の行と重複するキー値を持つすべての行に追加されます。これは単なる昇順の整数です。

一意として宣言されていない非クラスター化インデックスの場合、SQLServerは行ロケーターを非クラスター化インデックスキーにサイレントに追加します。これは、実際に重複している行だけでなく、すべての行に適用されます。

クラスター化された命名法とクラスター化されていない命名法は、列ストアのインデックスにも使用されます。ペーパー「SQLServer列ストアの機能強化」には次のように記載されています。

列ストアデータは実際にはどのキーでも「クラスター化」されていませんが、プライマリインデックスをクラスター化インデックスとして参照するという従来のSQLServerの規則を維持することにしました。

于 2014-06-28T19:16:11.637 に答える
174

これは非常に古い質問だと思いますが、上記の細かい答えを説明するのに役立つアナロジーを提供したいと思いました。

クラスター化されたインデックス

公共図書館に足を踏み入れると、本がすべて特定の順序で配置されていることがわかります(おそらくデューイ十進法(DDS))。これは、本の「クラスター化されたインデックス」に対応します。必要な本のDDS#がだった場合は005.7565 F736s、ラベルが付いている本棚の列などを見つけることから始めます001-099。(スタックの最後にあるこのエンドキャップ記号は、インデックスの「中間ノード」に対応します。)最終的には、というラベルの付いた特定の棚にドリルダウンし005.7450 - 005.7600、指定されたDDS#の本が見つかるまでスキャンします。その時点であなたはあなたの本を見つけました。

非クラスター化インデックス

しかし、あなたがあなたの本のDDS#を記憶した状態で図書館に入ってこなかった場合、あなたはあなたを助けるために2番目の索引が必要になるでしょう。昔は、図書館の前に「カード目録」と呼ばれる素晴らしい引き出しの局がありました。その中には何千もの3x5カードがありました-各本に1枚、アルファベット順に(おそらくタイトルで)ソートされています。これは「非クラスター化インデックス」に対応します。これらのカードカタログは階層構造で編成されていたため、各ドロワーには、含まれているカードの範囲(Ka - Klたとえば、「中間ノード」)のラベルが付けられます。もう一度、あなたはあなたの本を見つけるまでドリルインします、しかしこの場合、あなたがそれを見つけたら(すなわち、「葉のノード」)、あなたは本自体を持っていません、クラスタ化されたインデックスで実際の本を見つけることができるインデックス番号(DDS#)。

もちろん、図書館員がすべてのカードをコピーして、別のカード目録に別の順序で並べ替えることを妨げるものは何もありません。(通常、このようなカタログは少なくとも2つあります。1つは作成者名でソートされ、もう1つはタイトルでソートされます。)原則として、これらの「非クラスター化」インデックスは必要な数だけ持つことができます。

于 2016-10-26T21:06:10.680 に答える
74

クラスター化インデックスと非クラスター化インデックスのいくつかの特徴を以下に示します。

クラスター化インデックス

  1. クラスタ化インデックスは、SQLテーブルの行を一意に識別するインデックスです。
  2. すべてのテーブルは、クラスター化インデックスを1つだけ持つことができます。
  3. 複数の列をカバーするクラスター化インデックスを作成できます。例:create Index index_name(col1, col2, col.....)
  4. デフォルトでは、主キーを持つ列にはすでにクラスター化インデックスがあります。

非クラスター化インデックス

  1. 非クラスター化インデックスは、単純なインデックスのようなものです。これらは、データを高速に取得するために使用されます。一意のデータがあるかどうかわからない。
于 2013-01-21T14:21:23.847 に答える
56

クラスター化されたインデックス

クラスタ化インデックスは、テーブル内のDATAの物理的な順序を決定します。このため、テーブルには1つのクラスター化インデックス(主キー/複合キー)しかありません。

辞書」他の索引は必要ありません。すでに単語による索引です。

非クラスター化インデックス

非クラスター化インデックスは、ブックのインデックスに類似しています。データは1か所に保存されます。インデックスは別の場所に格納され、インデックスには格納場所へのポインタがあります。これは、データの高速検索に役立ちます。このため、テーブルには複数の非クラスター化インデックスがあります。

見つめている「生物学の本」には、章の場所を指す別のインデックスがあり、「終了」には、共通の単語の場所を指す別のインデックスがあります。

于 2018-01-21T18:47:09.060 に答える
53

非常に単純で非技術的な経験則では、クラスター化インデックスは通常、主キー(または少なくとも一意の列)に使用され、非クラスター化は他の状況(おそらく外部キー)に使用されます。 。実際、SQL Serverは、デフォルトで主キー列にクラスター化インデックスを作成します。ご存知のとおり、クラスター化インデックスは、データがディスク上で物理的に並べ替えられる方法に関連しているため、ほとんどの状況で総合的に選択できます。

于 2009-08-09T16:17:21.253 に答える
13

クラスター化されたインデックス

クラスタ化インデックスは、基本的にツリーで構成されたテーブルです。次の図に示すように、クラスター化インデックスは、ソートされていないヒープ表スペースにレコードを保管する代わりに、実際には、クラスターのキー列値の順に並べられたリーフ・ノードを持つB +ツリー索引であり、実際の表レコードを保管します。

クラスター化されたインデックス

Clustered Indexは、SQLServerおよびMySQLのデフォルトのテーブル構造です。テーブルに主キーがない場合でもMySQLは非表示のクラスターインデックスを追加しますが、テーブルに主キー列がある場合、SQLServerは常にクラスター化インデックスを作成します。それ以外の場合、SQLServerはヒープテーブルとして保存されます。

Clustered Indexは、通常のCRUDステートメントのように、クラスター化インデックスキーでレコードをフィルタリングするクエリを高速化できます。レコードはリーフノードに配置されているため、主キー値でレコードを検索するときに、追加の列値を検索する必要はありません。

たとえば、SQLServerで次のSQLクエリを実行する場合:

SELECT PostId, Title
FROM Post
WHERE PostId = ? 

実行プランがクラスター化インデックスシーク操作を使用してPostレコードを含むリーフノードを見つけ、クラスター化インデックスノードをスキャンするために必要な論理読み取りは2つだけであることがわかります。

|StmtText                                                                             |
|-------------------------------------------------------------------------------------|
|SELECT PostId, Title FROM Post WHERE PostId = @P0                                    |
|  |--Clustered Index Seek(OBJECT:([high_performance_sql].[dbo].[Post].[PK_Post_Id]), |
|     SEEK:([high_performance_sql].[dbo].[Post].[PostID]=[@P0]) ORDERED FORWARD)      | 

Table 'Post'. Scan count 0, logical reads 2, physical reads 0

非クラスター化インデックス

クラスター化インデックスは通常、主キー列の値を使用して構築されるため、他の列を使用するクエリを高速化する場合は、セカンダリ非クラスター化インデックスを追加する必要があります。

次の図に示すように、セカンダリインデックスはプライマリキーの値をリーフノードに格納します。

非クラスター化インデックス

したがって、テーブルのTitle列にセカンダリインデックスを作成すると、次のようになります。Post

CREATE INDEX IDX_Post_Title on Post (Title)

そして、次のSQLクエリを実行します。

SELECT PostId, Title
FROM Post
WHERE Title = ? 

インデックスシーク操作を使用して、IDX_Post_Title関心のあるSQLクエリプロジェクションを提供できるインデックス内のリーフノードを特定していることがわかります。

|StmtText                                                                      |
|------------------------------------------------------------------------------|
|SELECT PostId, Title FROM Post WHERE Title = @P0                              |
|  |--Index Seek(OBJECT:([high_performance_sql].[dbo].[Post].[IDX_Post_Title]),|
|     SEEK:([high_performance_sql].[dbo].[Post].[Title]=[@P0]) ORDERED FORWARD)|

Table 'Post'. Scan count 1, logical reads 2, physical reads 0

関連するPostId主キー列の値はリーフノードに格納されるため、このクエリでは、クラスター化インデックスで行IDX_Post_Titleを見つけるために追加のルックアップは必要ありません。Post

于 2021-06-13T12:25:02.510 に答える
5

クラスター化されたインデックス

クラスタ化インデックスは、キー値に基づいてデータ行を並べ替えてテーブルまたはビューに格納します。これらは、インデックス定義に含まれる列です。データ行自体は1つの順序でしかソートできないため、テーブルごとに1つのクラスター化インデックスしか存在できません。

テーブル内のデータ行がソートされた順序で格納されるのは、テーブルにクラスター化インデックスが含まれている場合のみです。テーブルにクラスター化インデックスがある場合、そのテーブルはクラスター化テーブルと呼ばれます。テーブルにクラスター化インデックスがない場合、そのデータ行はヒープと呼ばれる順序付けられていない構造に格納されます。

非クラスター化

非クラスター化インデックスは、データ行とは別の構造になっています。非クラスター化インデックスには非クラスター化インデックスのキー値が含まれ、各キー値エントリには、キー値を含むデータ行へのポインターがあります。非クラスター化インデックスのインデックス行からデータ行へのポインターは、行ロケーターと呼ばれます。行ロケーターの構造は、データページがヒープに格納されているかクラスター化されたテーブルに格納されているかによって異なります。ヒープの場合、行ロケーターは行へのポインターです。クラスタ化テーブルの場合、行ロケータはクラスタ化インデックスキーです。

非クラスター化インデックスのリーフレベルに非キー列を追加して、既存のインデックスキー制限をバイパスし、完全にカバーされたインデックス付きクエリを実行できます。詳細については、「含まれる列を含むインデックスの作成」を参照してください。インデックスキーの制限の詳細については、SQLServerの最大容量の仕様を参照してください。

参照:https ://docs.microsoft.com/en-us/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-describe

于 2017-08-28T00:10:59.620 に答える
4

データベースシステムから15.6.1から取られた「クラスタリングインデックス」に関する教科書の定義を提供させてください:完全な本

クラスタリングインデックスについても説明します。クラスタリングインデックスは、このインデックスの検索キーの値が固定されているすべてのタプルが、それらを保持できる数のブロックに表示されるような1つまたは複数の属性のインデックスです。

定義を理解するために、教科書で提供されている例15.10を見てみましょう。

R(a,b)属性でソートされ、その順序で格納され、ブロックにパックされたリレーションaは、確実にクラスター化されます。のインデックスaはクラスタリングインデックスです。これは、特定のa値a1に対して、その値を持つすべてのタプルaが連続しているためです。aしたがって、図15.14に示すように、-value a1を含む最初と最後のブロックを除いて、ブロックにパックされて いるように見えます。ただし、との値が非常に密接に相関bしていない限り、値が固定されたタプルはファイル全体に分散されるため、bのインデックスがクラスタリングされる可能性は低くなります。ab

図15.14

定義は、データブロックがディスク上で連続している必要があることを強制しないことに注意してください。検索キーを持つタプルが可能な限り少ないデータブロックにパックされていることだけを示しています。

関連する概念はクラスター化された関係です。タプルがそれらのタプルを保持できる可能性があるのとほぼ同じ数のブロックにパックされている場合、リレーションは「クラスター化」されます。言い換えると、ディスクブロックの観点から、異なるリレーションのタプルが含まれている場合、それらのリレーションをクラスター化することはできません(つまり、他のディスクブロックのリレーションのタプルを他のディスクブロックと交換することで、そのようなリレーションを格納するためのよりパックされた方法があります。タプルは、現在のディスクブロックのリレーションに属していません)。明らかに、R(a,b)上記の例ではクラスター化されています。

2つの概念を相互に接続するために、クラスター化された関係にクラスター化インデックスと非クラスター化インデックスを含めることができます。ただし、非クラスター化リレーションの場合、インデックスがリレーションの主キーの上に構築されていない限り、クラスター化インデックスは使用できません。

単語としての「クラスター」は、データベースストレージ側のすべての抽象化レベル(タプル、ブロック、ファイルの3つの抽象化レベル)にスパム送信されます。「クラスター化ファイル」と呼ばれる概念。ファイル(ブロックのグループ(1つ以上のディスクブロック)の抽象化)に、1つのリレーションまたは異なるリレーションのタプルが含まれるかどうかを記述します。ファイルレベルであるため、クラスタリングインデックスの概念とは関係ありません。

ただし、一部の教材では、クラスター化されたファイルの定義に基づいてクラスター化インデックスを定義するのが好きです。これらの2つのタイプの定義は、データディスクブロックまたはファイルの観点からクラスター化された関係を定義するかどうかに関係なく、クラスター化された関係レベルで同じです。この段落のリンクから、

ファイルの属性Aのインデックスは、次の場合にクラスタリングインデックスになります。属性値A = aのすべてのタプルがデータファイルに順次(=連続して)格納される

タプルを連続して格納することは、「タプルは、それらのタプルを保持できる可能性のあるほぼ少数のブロックにパックされます」と言うことと同じです(一方がファイルについて話し、もう一方がディスクについて話す場合はわずかな違いがあります)。これは、タプルを連続して格納することが、「それらのタプルを保持できる可能性のあるほぼ少数のブロックにパック」する方法であるためです。

于 2018-12-09T19:59:01.020 に答える
3

クラスター化インデックス: 主キー制約は、クラスター化インデックスがテーブルにまだ存在しない場合、クラスター化インデックスを自動的に作成します。クラスタ化されたインデックスの実際のデータは、インデックスのリーフレベルで保存できます。

非クラスター化インデックス:非クラスター化インデックス の実際のデータはリーフノードで直接検出されません。代わりに、実際のデータを指す行ロケーターの値しかないため、検索するために追加の手順を実行する必要があります。非クラスター化インデックスは、クラスター化インデックスとしてソートできません。テーブルごとに複数の非クラスター化インデックスが存在する可能性があります。実際には、使用しているSQLサーバーのバージョンによって異なります。基本的に、SQL Server 2005では249の非クラスター化インデックスが許可され、2008、2016などの上記のバージョンでは、テーブルごとに999の非クラスター化インデックスが許可されます。

于 2018-11-19T09:31:04.080 に答える
2

クラスター化インデックス-クラスター化インデックスは、データがテーブルに物理的に格納される順序を定義します。テーブルデータは唯一の方法で並べ替えることができるため、テーブルごとに1つのクラスター化インデックスしか存在できません。SQL Serverでは、主キー制約により、その特定の列にクラスター化インデックスが自動的に作成されます。

非クラスター化インデックス-非クラスター化インデックスは、テーブル内の物理データを並べ替えません。実際、非クラスター化インデックスは1つの場所に格納され、テーブルデータは別の場所に格納されます。これは、本の内容が1つの場所にあり、索引が別の場所にある教科書に似ています。これにより、テーブルごとに複数の非クラスター化インデックスが可能になります。ここで重要なのは、テーブル内でデータがクラスター化インデックスによってソートされることです。ただし、非クラスター化インデックス内では、データは指定された順序で格納されます。インデックスには、インデックスが作成された列の値と、その列の値が属するレコードのアドレスが含まれます。インデックスが作成された列に対してクエリが発行されると、データベースは最初にインデックスに移動して、テーブル内の対応する行のアドレス。次に、その行アドレスに移動し、他の列の値をフェッチします。非クラスター化インデックスがクラスター化インデックスよりも遅いのは、この追加の手順によるものです。

クラスター化インデックスと非クラスター化インデックスの違い

  1. テーブルごとに存在できるクラスター化インデックスは1つだけです。ただし、1つのテーブルに複数の非クラスター化インデックスを作成できます。
  2. クラスタ化インデックスはテーブルのみを並べ替えます。したがって、余分なストレージを消費しません。非クラスター化インデックスは、より多くのストレージスペースを要求する実際のテーブルとは別の場所に格納されます。
  3. クラスター化インデックスは、追加のルックアップ手順を必要としないため、非クラスター化インデックスよりも高速です。

詳細については、この記事を参照してください。

于 2020-05-20T10:03:48.180 に答える