非クラスター化インデックスをSQLAzureDBに追加している最中ですが、単一の非クラスター化インデックスに複数の列があり、それぞれに単一の列がある複数の非クラスター化インデックスとの違いは何ですか?
2 に答える
単一の非クラスター化インデックスに複数の列を持つことと、それぞれに単一の列を持つ複数の非クラスター化インデックスを持つことの違いは?
T
クラスター化された PKId
列と、さらに列A
、B
、を含むテーブルを考えてみましょうC
。
A
、B
、およびを含む単一の非クラスター化インデックスは、C
次のようなクエリの高速検索をサポートできます。
WHERE A > @a
WHERE A = @a AND @b1 < B AND B < @b2
WHERE A = @a AND B = @b AND C < @c
だがしかし
WHERE B = @b
WHERE C = @c
どちらの場合も、テーブル スキャンよりも優れた方法はありません。
ただし、IX_A
上A
などに複数のインデックスがある場合:
WHERE A = @a
WHERE B = @b
WHERE C = @c
インデックス、および次のような複合クエリの恩恵を受けます。
WHERE A = @a AND B = @b AND C < @c
メリットも小さいでしょう。
それらが最適化するSELECT
クエリは異なります。
クエリパフォーマンスの最適化を必要とせずにインデックスを追加するべきではありません。
最適化するクエリがある場合は、最適化するクエリに対応するインデックスを追加することを検討し始めることができます。
次の構造を含むテーブルがあるとします。
create table emp
(
id int identity primary key clustered,
name nvarchar(200),
dep_id int,
salary int
);
クラスタ化インデックス(句)は、次のようなフィルタとして列をprimary key clustered
使用して、クエリの検索と行データの取得を高速化します。id
select id, name, dep_id, salary
from emp
where id = @id
任意の(一意の)列の非クラスター化インデックスは、フィルターと同じ列を使用して(行データの取得ではなく)ルックアップを高速化します。
create index emp_name_idx on emp(name);
-- will speed up look-up for
select id, dep_id
from emp
where name = @name
SELECT
同じインデックスを使用して行データの取得も高速化する場合は、句に含まれる列を含まれる列に追加する必要があります。
create index emp_name_idx on emp(name) include(id, dep_id);
-- will speed up look-up and data row retrieval for
select id, dep_id
from emp
where name = @name
複数の列を含む非クラスター化インデックスは、インデックスに表示されるのと同じ順序で最初のn列を使用するクエリの検索を高速化します(フィルターが等式比較である限り、列最適化ストリークは最初の不等式として終了します)比較が満たされます)。
create index emp_namesalary_idx on emp(dep_id, salary);
-- will speed up look-up and data row retrieval for
select id, dep_id
from emp
where dep_id = @dep_id
and salary > @salary
単一列インデックスの場合、行データの取得も最適化するには、この句を使用して、インデックス列リストにまだ存在していない句include
内のすべての列を指定します。SELECT
INSERT
テーブルに追加するすべてのインデックスについて、このテーブルのオーバーヘッドも追加することに注意してください。SELECT
したがって、ステートメントのインデックスからの利益と、ステートメントの損失との間で常にパフォーマンスのバランスをとる必要がありINSERT
ます。インデックスはディスク(およびキャッシュ)スペースを使用し、それも決定プロセスでカウントされる必要があることも忘れないでください。