web-dev-qa-db-ja.com

主キーに含まれる列を持つ2番目のインデックスを持つことの利点は何ですか?

データベースを確認したところ、特定のテーブルに次のインデックスがあることがわかりました。

Col1    INT IDENTITY(1,1) Primary Key
Col2    INT
...
about 15 more columns
....
ColN   VARCHAR(50)
....
another 10 more columns

Col1の標準的な主キーのクラスター化インデックスに加えて、次のインデックスもあります。

create nonclustered index [iTable-Col1] ON [dbo].[Table1]
(
    Col1
)
include ( ColN )

私たちは定期的にCol1で検索し、ColNのみを取得したいと考えています。このインデックスは、クエリを満たすために必要なすべてのデータを含む最小のインデックスであるため、使用されます。

私の質問は、このインデックスはSQL Serverに何らかの利点をもたらすのですか?それを削除して、クラスター化インデックスを検索するほうがよいでしょうか?

私の唯一の考えは、このインデックスはクラスター化インデックス(25mb vs 300mb)よりもはるかに小さいため、検索やキャッシュが高速になる可能性があるということです。

違いがある場合、サーバーはSQL Server 2012です。

7
Greg

ほとんどの場合、このタイプのインデックスは、これらの列に対するインデックススキャンにのみ役立ちます。

リーフレベルの上のインデックスツリー構造は、通常、ツリーレベルの点で非常に似ています。その場合、seek操作のツリーをナビゲートしてもパフォーマンスにほとんどまたはまったく違いはありません。 (それもスキャンしません)。インデックスの内部の基本を学びたい場合は、ビデオ here を参照してください。

とにかく、スキャンに戻ります。このインデックスが役立つ理由は、インデックス自体ではなく、クラスタ化インデックスをスキャンする(またはそれらのデータページをメモリに保持する)理由が多くない。他の列がテーブルを比較的広くする場合(指定したサイズに基づいて、データベース全体のコンテキストでこのテーブルがどのくらい大きいかは不明ですが、そうします)、狭いインデックス場合によってはメリットがあるかもしれません。頻繁なスキャン(または多くの異なるキー値のシーク)は、インデックス全体をメモリに保持する傾向があるため、インデックスが大きいほど、他のオブジェクト用のメモリ領域が少なくなり、もちろん、これにより、I/Oが増加します。バッファプールは冷たいです。

これはまれな使用例ですが(覚えているので、1回または2回行っています)、この種類のインデックスの最大の利点は、マージ結合を使用してこのテーブルを結合するクエリに非常に役立つことです。 (注:インデックススキャンが適切でない場合は、クエリを最適化してくださいfirst!)クエリプランでは、クラスター化インデックスのスキャン、または非クラスター化インデックスのスキャンと並べ替えマージ結合の前に、これがいつ良いアイデアになるかを示すことができます。しかし、これはまれです。クエリは十分な頻度で実行する必要があります。または、ベーステーブルがメモリ内に留まるのに十分なコストがかかる(つまり、常にそこに必要としない必要がない)。インデックスの保存とメンテナンス。

howこのインデックスが現在使用されているか不明な場合は、DMVを確認してください sys.dm_db_index_usage_stats 。カウントはサーバーの再起動時にリセットされることに注意してください。したがって、インデックスの削除を検討している場合は、ビジネスサイクル全体の間、インデックスが役に立たないことを確認してください。

8
Jon Seigel

SQL Serverに質問に答えさせてください。インデックスが役立つ場合、クエリオプティマイザーはそれを使用しますが、そうでない場合は使用しません。

0