32

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

問題は、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]ます-これにより、インデックスが無視されるようになると思います。

これらは両方とも非常に厄介なようです-私は実際に範囲比較を行ったり、テーブルをスキャンしたりしたくありません。

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

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

4

4 に答える 4

35

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

その記事から:

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;

また、その記事から:、、またはすべてを使用BETWEENするとDATEDIFF遅くCONVERT(CHAR(8)...なります。

于 2013-03-11T22:43:37.390 に答える
14

次に例を示します。

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'

ここにあります

于 2013-03-11T17:25:44.223 に答える
0

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

于 2013-03-11T21:52:31.957 に答える
0

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

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

于 2016-07-26T06:50:43.553 に答える