MONTH(column)
と はサージ可能ではないため、テーブル全体をスキャンするYEAR(column)
必要があり、 SQL Server に の意味を伝えていませんTOP
。10行が見つかった場合、SQL Serverが短絡できる可能性があるのは事実ですが、それが発生した場合、スキャンがはるかに進んでいる可能性があり、違いは最小限です。これは特に、where 句に一致する行が 0 行または 10 行未満の場合に当てはまります。
はるかに優れたWHERE
条項は次のとおりです。
WHERE SomeDate >= '20110501' AND SomeDate < '20110601';
文字列を構築したくない場合は、それらをパラメーター/変数として渡し、次のようにします。
DECLARE @year INT;
DECLARE @month INT;
SET @year = 2011;
SET @month = 5;
...
WHERE SomeDate >= DATEADD(MONTH, @month-1, DATEADD(YEAR, @year-1900, '19000101'))
AND SomeDate < DATEADD(MONTH, @month, DATEADD(YEAR, @year-1900, '19000101'));
いずれの場合も、 にインデックスがあればSomeDate
、それを使用でき、テーブル スキャンを回避できます。10 行しか探していなくても、ショート サーキットが発生する可能性がある場合でも、5 億行のテーブルでのテーブル スキャンは避けたいと考えています。
ただし、テーブル スキャンがなくても、このクエリは依然として非効率的です。本当にすべての列が必要ですか? インデックスSomeDate
が使用されている場合でも、残りの列を取得するために、シークでクラスター化インデックスまたはカバリング インデックスを検索する必要があります。これらの列が必要ない場合は、含めないでください。
bluefeet が指摘したように、 SQL Serverにどの10 を意味するかTOP 10
を伝えていない場合、このようなことは意味がありません。が適切なインデックスを使用する場合は、とにかく使用しないことで回避していると思われる追加のコストのかかる並べ替え演算子を回避できます。ORDER BY
ORDER BY
ORDER BY