4

SQLServerに約100万行のテーブルがあります。ID(PK)、ステータス(int)、および日時列があります。また、日時列にインデックスを作成しました。

今、私は理解できない効果を見つけました。

SELECT status
FROM table
WHERE dateTime BETWEEN '2010-01-01T00:00:00' AND '2010-01-02T12:00:00'

このステートメントは3664行を返します。約150ミリ秒実行され、実行プランは、キールックアップを使用してインデックスシークを実行することを示しています。

さて、次のように変更すると(時間を12から13に変更するだけです):

SELECT status
FROM table
WHERE dateTime BETWEEN '2010-01-01T00:00:00' AND '2010-01-02T13:00:00'

このステートメントは3667行を返します。実行時間は約600ミリ秒で、抽出計画では主キーを使用していることが示されています。

分かりません。3667以上の行では、シークがはるかに高速であっても、常に主キーを使用します。

説明はありますか?

4

1 に答える 1

5

statusはインデックスに含まれていないdatetimeため、この値を取得するには、一致する行ごとにキールックアップを実行する必要があります。

範囲が拡大するにつれて(したがって、必要なルックアップの数が増えるにつれて)、ルックアップを回避して(カバーする)クラスター化インデックス全体をスキャンするだけの方が高速になると推定されます。あなたの場合はおそらく間違っています。あるプランから別のプランに切り替わるポイントは、転換点と呼ばれます。

推定行数と実際の行数がうまくいかないかどうかを確認する必要があります(おそらく、統計が最後に更新されてから、範囲に一致するいくつかの行が削除されています)。

または、高レベルの断片化のため、またはその他の理由で、作成されたコストの仮定が環境の実際の相対的なパフォーマンスを反映していないため、インデックススキャンはコストの仮定よりも高価である可能性があります。

于 2012-10-11T18:43:15.213 に答える