6

dateフィールドに等しいフィールドに基づいて行を返していdatetimeます。それらは明らかに、の形式の場合にのみ直接一致しますがdd/MM/yyyy = dd/MM/yyyy 00:00:00、時間を無視しようとしています。

私が試した3つの方法がありますが、どれもうまくいきますが、何が最善なのか疑問に思っています.

1 -CONVERT(varchar(10),MyDate,103) = CONVERT(varchar(10),MyDateTime,103))

2 -MyDate = CONVERT(date,MyDateTime)

3 -MyDate = CAST(MyDateTime AS date)

4 -MyDate = DATEADD(dd, DATEDIFF(dd, 0, MyDateTime), 0)

私にとっては、#1が最も遅く、文字列に変換してから文字列比較を使用するのが最も効率的ではないはずです。しかし、テストでは最速です!以下は私のテストです:

1 - 平均 303 ミリ秒

2 - 平均 284 ミリ秒

3 - 平均 273 ミリ秒

4 - 平均 1745 ミリ秒

テストは〜300,000のサンプルサイズからのものです

これには理由がありますか?最初のオプションは本当に最良のオプションですか?

編集: 300k レコードに対してそれぞれ 10 回実行されるテストを反映するようにテスト値を変更しました。DATEADD/DATEDIFF結果を変更して、後述の Tim Schmelterの方法を除いて、すべてがかなり似ていることを示します。これは最も効率が悪いと言えます。

4

2 に答える 2

4

#3が最良の選択だと思います。これが私の理由です。

あなたはすでにパフォーマンス作業を行っているので、やり直しはしません。更新された数値は、オプション 1 ~ 3 が非常に似ていることを示しているため、#4 を除外することを除いて、パフォーマンスを脇に置くことができます。

パフォーマンスが決まれば、次はベスト プラクティスと読みやすさです。#1は間違いなくほとんどのコードにとって最も読みにくいので、除外します。これと同じ理由が、既に除外されている #4 にも当てはまります。

これにより、#2 と #3 が残ります。CAST は SQL 標準の一部であり、CONVERT よりも移植性が高いため、私の選択は #3 になります。したがって、CONVERT の特別な機能が必要ない場合は常に CAST を使用することをお勧めします。

于 2015-02-10T01:58:06.230 に答える
1

がパラメーターの場合MyDate、5 番目のオプションがあります。

MyDateTimeの間にあるかどうかを確認します[MyDate, MyDate + 1 DAY)。その列にインデックスがある場合、このクエリはインデックス スキャンの代わりにインデックス シークを使用できます。

DECLARE @MyDate1 AS DATETIME = '2015-01-01'              -- 2015-01-01 00:00:00
DECLARE @MyDate2 AS DATETIME = DATEADD(DAY, 1, @MyDate1) -- 2015-01-02 00:00:00
SELECT ... WHERE MyDateTime >= @MyDate1 AND MyDateTime < @MyDate2
于 2015-05-14T13:17:32.643 に答える