web-dev-qa-db-ja.com

Microsoft SQLサーバーで日付を比較する最適な方法は何ですか?

非常に大きなテーブルにSQL datetimeフィールドがあります。インデックスが作成されており、クエリが必要です。

問題は、SQLが常に時刻コンポーネントを格納することです(常に真夜中であっても)が、検索は時刻ではなく日に対して行われます。

declare @dateVar datetime = '2013-03-11;

select t.[DateColumn]
from MyTable t
where t.[DateColumn] = dateVar;

t.[DateColumn]には常に時間コンポーネントが含まれるため、何も返されません。

私の質問は、これを回る最善の方法は何ですか?

オプションには主に2つのグループがあるようです。

  1. dateaddを使用して2番目の変数を作成し、between ... andまたは>= ... and ... <=を使用します。

  2. t.[DateColumn]を日付のみのコンポーネントに変換します-これにより、すべてのインデックスが無視されます。

これらはどちらも非常に厄介に見えます-範囲の比較やテーブルのスキャンは本当にしたくありません。

もっと良い方法はありますか?

これらのオプションのいずれかが一貫して最適な方法である場合、どのように、なぜですか?

28
Keith

いずれの場合でも、DATEに変換するか、無制限の日付範囲を使用すると、最高のパフォーマンスが得られます。参考までに、インデックスを使用して日付に変換するのが最高のパフォーマンスです。記事のさまざまなテクニックをさらにテスト: datetimeから時間をトリムする最も効率的な方法は何ですか? アーロンバートランド投稿

その記事から:

_DECLARE @dateVar datetime = '19700204';

-- Quickest when there is an index on t.[DateColumn], 
-- because CONVERT can still use the index.
SELECT t.[DateColumn]
FROM MyTable t
WHERE = CONVERT(DATE, t.[DateColumn]) = CONVERT(DATE, @dateVar);

-- Quicker when there is no index on t.[DateColumn]
DECLARE @dateEnd datetime = DATEADD(DAY, 1, @dateVar);
SELECT t.[DateColumn] 
FROM MyTable t
WHERE t.[DateColumn] >= @dateVar AND 
      t.[DateColumn] < @dateEnd;
_

また、その記事から:BETWEENDATEDIFF、またはCONVERT(CHAR(8)...の使用はすべて低速です。

29

以下に例を示します。

OrderDateというDateTimeフィールドを持つOrderテーブルがあります。注文日が2006年1月1日であるすべての注文を取得したい。次の方法があります:

1) WHERE DateDiff(dd, OrderDate, '01/01/2006') = 0
2) WHERE Convert(varchar(20), OrderDate, 101) = '01/01/2006'
3) WHERE Year(OrderDate) = 2006 AND Month(OrderDate) = 1 and Day(OrderDate)=1
4) WHERE OrderDate LIKE '01/01/2006%'
5) WHERE OrderDate >= '01/01/2006'  AND OrderDate < '01/02/2006'

見つかった ここ

11
paraselena

日付がfromdateとtoDateの間にあるときにアイテムを取得します。

ここで、convert(date、fromdate、103)<= '2016-07-26'およびconvert(date、toDate、103)> = '2016-07-26'

0
gaze

時刻なしで日付のみを含む計算列を追加できます。 2つのオプションの間では、BETWEEN演算子を使用します。これは、それが "クリーン"であり、インデックスをより有効に使用する必要があるためです。実行計画を比較すると、BETWEENの方が速いことがわかります。ただし、実際のテストでは同じことを実行しました。

0
Michael L.