2017-09-12 4 views
1

4つの列を持つ 'demo'というテーブルがあると仮定します。 'a'、 'b'、 'c'、 'd' 'demo'テーブルのprimary keyclustered indexには、 'a'と 'b'の順に列が含まれています。クエリの参照テーブル「デモ」からクラスタ化されていないインデックスにプライマリキー列がどのように含まれているか理解する

の実際の実行計画は、「新しいnon-uniquenon-clustered indexが列「B」とすべきであるinclude列「A」のために必要であることを示唆しています。

私は列「B」にnon-uniquenon-clustered indexを作成した場合、私はinclude列「A」に必要なのですか、それはprimary keyであるので、それはすでにnon-clustered indexの一部になりますか?

プライマリキー列 'a'がすでに非クラスタ化インデックスの一部である場合、列 'a'はinclude列として格納されているのか、非クラスタ化キーの一部ですか?

+4

この列はプライマリキーではなくクラスタ化されたインデックスキーに含まれているためです。プライマリキー制約をサポートするインデックスは、あなたのケースではクラスタードインデックスでもあります。 (確かに、最も一般的なケースですが、明示的にする価値があります)。残りについては、[こちら](https://dba.stackexchange.com/questions/57465/necessary-to-include-clustered-index)を参照してください。非クラスタ化インデックス内の列)。 –

答えて

1

「実際の実行計画」をクエリ参照テーブルから「デモ」は、新たな非ユニーク非こと を示唆しています 列 'b'にはクラスタード・インデックスが必要であり、列 'a'を含める必要があります。

...

主キー列「」既に非クラスタ化インデックスの一部である、 は列「」を含む列として格納されているか、 非クラスタ化キーの一部である場合?あなたのケースでは

aは、クラスタ化インデックスキーの一環として、非クラスタ化インデックスのすべてのレベルで表示されます。あなたに提案されたインデックスはnon-uniqueなので、uniquefierが必要で、この目的のためにクラスタ化インデックスキーが使用されます。

提供インデックスがユニークであった場合、カラムaは、クラスタテーブルの場合にはインデックスキーをクラスタ化していることを行ロケータの一部として、このインデックスのリーフレベルに格納されます。

aは、明示的にインデックスのincluded columnとして含めると2回保存されないので、それを含めるようにアドバイスします。誰かがクラスタ化されたテーブルをヒープにすることを決めたとき(クラスタ化されたインデックスを削除すること)には違いがあります。この場合、クラスタ化されていないインデックスに列aを明示的に含めないと、インデックスは失われ、クラスタ化されていないインデックスには含まれなくなります。

0

これを試して実行計画を見てください。 DBではINDEXのみが使用されています。ですから、私が知る限り、インデックスに列Aを含めるべきではありません(あなたが言ったように、Clust。インデックスキーは既に含まれています)。

CREATE TABLE DEMO (COLA VARCHAR(10) NOT NULL, COLB VARCHAR(10) NOT NULL, COLC VARCHAR(10), COLD VARCHAR(10)); 

ALTER TABLE DEMO ADD CONSTRAINT DEMO_PK PRIMARY KEY (COLA, COLB); 

CREATE INDEX DEMO_IX1 ON DEMO (COLB); 



INSERT INTO DEMO VALUES ('A','B','C','D'); 
INSERT INTO DEMO VALUES ('A1','B1','C1','D1'); 
INSERT INTO DEMO VALUES ('A2','B2','C2','D2'); 

SELECT COLA,COLB FROM DEMO WHERE COLB='B1' 
0

非クラスタ化インデックスには、暗黙的にクラスタ化インデックスキーが自動的に含まれます。非クラスタ化インデックスのリーフ層はインデックスページの代わり で構成されて

非クラスタ化インデックスの建築

documentationあなたはこのことについて多くの情報を得ることができるが、特にこの部分はまさにこのことを説明して のデータページ。非クラスタ化インデックス行の行ロケータは、行へのポインタまたは行のクラスタードインデックスキーのいずれかである です。

テーブルがヒープの場合、行ロケータはキー値を含むデータ行を直接指しますが、テーブルがヒープでない場合(この場合、既にクラスタ化されたキーがあるためその行のロケータはクラスタ化されたインデックスキーを指しています)。

clustered and nonclustered indexes describedもご覧ください。

このスレッドは同じについて説明します。これは、クラスタ化インデックスキーの一部であるため、非クラスタ化インデックスの列a含めるNecessary to include clustered index columns in non-clustered indexes?

0

は無用です。したがって、非クラスタ化インデックスのリーフ・ページのデータの一部です。

SELECT a FROM tab WHERE b = <value> 

このようなクエリを持つことは、その後 a値が自然に非クラスタ化インデックスのリーフデータの一部となります。

+1

NCI on(b)は一意ではないため、aはインデックスのキー列になります。したがって、リーフページに存在するだけでなく、 http://sqlblog.com/blogs/kalen_delaney/archive/2010/03/07/more-about-nonclustered-index-keys.aspx –

0

PKフィールドは、常にインデックスのキーの一部であり、含まれる列の一部ではありません。

私がここで考えているのは、恐らく列Bを探したいということです。これは、列Bが索引の最初のキーである場合にのみ可能なことです。列Bを最初に、列Aを後にしてインデックスを定義すると、おそらくそれだけでインデックスを作成できます。あなたが複合PKを持っているので、両方のキーがインデックスにある限り、それはうまくいくように思えますが、現在は間違った順番(最初のA、次にB)にある可能性があります。

自動的にインデックスに現れてPKフィールドのリファレンス:https://www.brentozar.com/archive/2013/07/how-to-find-secret-columns-in-nonclustered-indexes/

+1

「PKフィールドは常にインデックスのキーの一部であり、含まれている列「むしろ、むしろ」Clustered Index列は、一意でないNCIのキー列として格納され、一意のNCIの列も格納されます。 http://sqlblog.com/blogs/kalen_delaney/archive/2010/03/07/more-about-nonclustered-index-keys.aspxを参照してください。 –

関連する問題