web-dev-qa-db-ja.com

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

この質問は、SQL Serverインデックス技術の有効性についてです。 「インデックス交差点」と呼ばれていると思います。

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

テーブルには多くの検索可能な列があります。開発者は、検索可能な列ごとに1つの列インデックスを作成しました。理論では、SQL Serverはこれらの各インデックスを結合(交差)して、mostの状況で効率的にテーブルにアクセスできます。以下は簡単な例です(実際のテーブルにはより多くのフィールドがあります):

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つのインデックスシークでハッシュ一致を実行することを示すクエリプランを見てきました。テーブルの検索方法がわからない場合、これはおそらく意味がありますか?ありがとう。

36
RaoulRubin

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

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

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

そして、あなたの質問に具体的に答えるために:各列に個別のインデックスcanは、各列に高い選択性があることを条件として(多くの異なる値、各値がデータベース)。 2つのインデックスレンジスキャン間でハッシュ結合を使用して作成されたアクセスプランは通常、非常にうまく機能します。選択性の低い列(個別の値がほとんどなく、各値がデータベースに何度も表示される)は、それ自体でインデックスを付ける意味がなく、クエリオプティマイザーはそれらを単に無視します。ただし、選択度の低いカラムは、選択度の高いカラムとペアになっていると、何度もcompositeキーが適切になります。

39
Remus Rusanu