web-dev-qa-db-ja.com

一意の列を持つ非クラスター化インデックスは、常に最初にその列をフィルターするすべてのクエリに対応しますか?

インデックスが大きく、たとえば列が異なる複数の異なる非クラスター化インデックスがある大きなヒープテーブルを見つけましたが、それらのインデックスの一部には、最初のインデックス列として設定された(1つだけ存在する)主キー列があります。

私はいくつかの調査を行い、インデックスとクエリをいじって、確実に専門家によって確認されてほしいと結論づけました。

質問1:最初のインデックス列として主キー列に基づくインデックスを1つだけではなく、主キーに基づいて複数のインデックスを作成するのはナンセンスだと言ってもいいでしょう。たった一列? (追加のフィルター、結合、または選択された列が、クエリを完全にカバーし、RIDルックアップを回避するために含まれる列としてインデックスに入れられると仮定します)

質問2:テーブルの主キーに基づく非クラスター化インデックスは、常に一意のインデックスとして作成する必要があると言うのは正しいですか? (SQLサーバーはすでにpkを含むインデックスが一意になることを知っているはずなので、何らかの理由でオプションの設定です...)

4
Magier
  1. はい、質問の制約を考慮すると、特に主キー列がインデックスの先頭列であることがわかります。また、主キーは決して変更されないと仮定します。

  2. 必ずしも。

    オプティマイザーは、非クラスター化インデックスに一意のマークを付けなくても、一意性を推測できます。

    インデックスに一意のマークを付けると、インデックスキーを変更する実行プランで Split-Sort-Collapseを導入 の組み合わせになります。特に追加のソートは、パフォーマンスに影響を与える可能性があります。

    一方、インデックスに一意のマークを付けないと、主キーが変更された場合にデータの整合性が失われます。

CREATE TABLE dbo.Test
(
    pk integer PRIMARY KEY NONCLUSTERED,
    c1 integer NOT NULL,
    c2 integer NOT NULL
);

-- Not unique on pk, c1
CREATE NONCLUSTERED INDEX ic1 ON dbo.Test (pk, c1);

-- Unique on pk, c2
CREATE UNIQUE NONCLUSTERED INDEX ic2 ON dbo.Test (pk, c2);

独自性

-- Neither plan has an aggregate
SELECT DISTINCT T.c1 FROM dbo.Test AS T WHERE T.pk = 1;
SELECT DISTINCT T.c2 FROM dbo.Test AS T WHERE T.pk = 1;

No aggregates

分割、並べ替え、折りたたみ

-- No split, sort, collapse
UPDATE dbo.Test SET c1 = CHECKSUM(NEWID());

Simple update

-- Split, sort, collapse updating unique key
UPDATE dbo.Test SET c2 = CHECKSUM(NEWID());

SSC plan

Split-sort-collapseプランも ワイド(インデックスごと)更新 であることに注意してください。

ただし、一意性は大きなトピックです。私は通常一意であるものを一意であるとマークします。私のブログからさらに読む:


ヒープテーブルに関するコメントを予測するには:ほとんどのテーブルは、クラスター化することでメリットを得ます。テーブルで削除が発生した場合、特にスペース管理の観点から、ヒープ構造を選択する十分な理由が必要です。列が元のページ(転送されたレコード)で使用可能なスペースを超えて拡張される場合、更新によりパフォーマンスに影響が生じる可能性もあります。

6
Paul White 9