特定の複数列インデックスの代わりに、多くの単一フィールドインデックスを使用する必要がありますか?


35

この質問は、SQL Serverのインデックス作成手法の有効性に関するものです。「インデックスの交差点」として知られていると思います。

多数のパフォーマンスと安定性の問題がある既存のSQL Server(2008)アプリケーションを使用しています。開発者は、インデックス作成に関して奇妙なことをしました。私はこれらの問題に関する決定的なベンチマークを得ることができませんでしたし、インターネット上で本当に良いドキュメントを見つけることもできませんでした。

テーブルには多くの検索可能な列があります。開発者は、検索可能な各列に単一の列インデックスを作成しました。理論は、SQL Serverはこれらの各インデックスを結合(交差)して、ほとんどの状況でテーブルに効率的にアクセスできるというものでした。簡単な例を次に示します(実際のテーブルにはさらにフィールドがあります)。

CREATE TABLE [dbo].[FatTable](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [col1] [nchar](12) NOT NULL,
    [col2] [int] NOT NULL,
    [col3] [varchar](2000) NOT NULL, ...

CREATE NONCLUSTERED INDEX [IndexCol1] ON [dbo].[FatTable]  ( [col1] ASC )
CREATE NONCLUSTERED INDEX [IndexCol2] ON [dbo].[FatTable] ( [col2] ASC )

select * from fattable where col1 = '2004IN' 
select * from fattable where col1 = '2004IN' and col2 = 4

検索条件を対象とした複数の列インデックスははるかに優れていると思いますが、間違っているかもしれません。SQL Serverが2つのインデックスシークでハッシュマッチを実行することを示すクエリプランを見てきました。テーブルの検索方法がわからない場合、おそらくこれは理にかなっていますか?ありがとう。


@brentozarには、見る価値のあるインデックスに関する素晴らしいビデオがあります。brentozar.com
server

回答:


38

必要なのはインデックスをカバーすることです。独自にクエリを満たすことができるインデックス。しかし、「カバー」インデックスには1つの問題があります。それは特定のクエリをカバーすることです。したがって、適切なインデックス作成戦略を開発するためには、ワークロードを理解する必要があります。どのクエリがデータベースにヒットしているか、どのクエリがクリティカルでどれがクリティカルではないか、各クエリの実行頻度などです。これを各インデックスの書き込みおよび更新コストとバランスさせて、インデックス作成戦略を立てます。複雑に聞こえるのは、それ複雑だからです

ただし、いくつかの経験則を適用できます。MSDNは基本を非常によくカバーしています。

コミュニティによって投稿された無数の記事もあります。Webcast Recording – DBA Darwin Awards:Index Edition

また、具体的に質問に答えるには、各列に高い選択性(多くの異なる値があり、各値がデータベースに数回しか現れない場合)があれば、各列の個別のインデックス機能します。2つのインデックス範囲スキャン間でハッシュ結合を使用した結果のアクセスプランは、通常非常にうまく機能します。選択性の低い列(個別の値がほとんどなく、各値がデータベースに何度も表示される)は、それ自体でインデックスを作成しても意味がありません。クエリオプティマイザーは単にそれらを無視します。ただし、選択度の低いカラムは、選択度の高いカラムとペアにすると、多くの場合、優れた複合キーになります。


ありがとうレムス。個別のインデックスを使用する場合と比べて、ターゲットの複数列インデックスを作成する(および含める)ことの相対的な利点について疑問に思っています。「非常にうまく機能する」ことで十分であれば、問題ないかもしれません。(低選択性フィールドのインデックスは除外されます)。この手法は、実稼働データベースにアクセスできず、インデックスを実際の使用にターゲットできない場合に役立ちます。
ラウルルビン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.