2

3列のテーブルがあります:ID, FirstName, Salary.

IDにクラスター化インデックスがあり、このクエリを実行すると

select * from table where FirstName = 'a'

クラスター化インデックス スキャンを使用して結果を取得し、名前に非クラスター化インデックスを追加するように求めてきました。

に非クラスター化インデックスを追加するとFirstName、 の結果として結果が得られIndex Seekます。

インデックス シークの理由がわかりません。非クラスター化インデックスはデータを並べ替えないので、スキャンするべきではありませんか?

4

1 に答える 1

1

条件 ( ) に一致する行の数FirstName = 'a'が十分に少ない場合、SQL Server クエリ オプティマイザーはindex seek、非クラスター化インデックス内の を使用して、その条件に一致する行を検索し、2 番目のステップで、Key lookupメインデータページに移動して、すべてのデータ列を取得します (を使用しているためSELECT * ..)。

インデックス シーク + キー ルックアップがクラスター化されたインデックス スキャンよりも効率的である場合を決定するのは、オプティマイザー次第です。これは主に選択性に依存します。条件に一致する行が多すぎる場合は、クラスター化インデックス スキャンが代わりに実行されます。

クエリ オプティマイザーがこのような決定を下せるようにする "魔法" は、SQL Server が保持するデータとデータ分布に関する統計です。インデックスと、テーブル内の追加の選択的な列の両方についてです。

また、統計が古くなっている場合 (多くの更新と削除を行ったため)、クエリ オプティマイザーが非効率的または不適切な実行プランを使用する可能性は十分にあります。これは、主要なパフォーマンスの問題の 1 つです。統計が適切に維持され、最新であることを常に確認してください。(たとえば、毎晩または毎週統計を更新するメンテナンス プランを使用することにより - 大量のデータを操作する頻度に応じて)。

于 2013-09-24T14:15:08.500 に答える