9

日付付き(時刻なし)の日時のレコードセットに対するクエリに対する「ベストプラクティス」アプローチとは何かを知りたいと思いました。

日時データ型を使用するレコードセットから、日付範囲に基づいてレコードを返すいくつかのクエリを使用します。つまり、各レコードは範囲間を使用してチェックする必要があります。

クエリの例は次のとおりです。

Select * 
FROM Usages 
where CreationDateTime between '1/1/2012' AND '1/2/2012 11:59:59'

使用することBETWEENはリソースを大量に消費することであり、日付の日時データ型をチェックすることは常に非常にリソースを消費することになることを私は知っていますが、この状況で他の人が何を使用するか(または使用するか)を聞きたいです。

日時レコードを次のような日付に変換すると、パフォーマンスが向上しますか?

Select * 
FROM Usages 
where CONVERT(DATE,CreationDateTime) between '1/1/2012' AND '1/2/2012'

または、それよりも小さい/大きいのチェックを行う可能性がありますか?

Select * 
FROM Usages 
where (CreationDateTime > '1/1/2012') 
    AND (CreationDateTime < '1/2/2012 11:59:59')
4

2 に答える 2

11

あなたが知っていると思っていることは正しくありません。

BETWEENDATETIME データ型を使用することも、リソースを大量に消費することもありません。

列にインデックスを付け、列が実際には VARCHAR() ではなく DATETIME であり、フィールドを関数でラップしていなければ、すべてがうまくすばやく処理されます。

つまり、代わりに>=andを使用し<ます。パフォーマンスのためではなく、論理的な正しさのためです。

WHERE
  myField >= '20120101'
  AND myField < '20120102'

これは、フィールドに時間、分、または (神話上のデータ型で) ピコ秒が含まれているかどうかに関係なく機能します。

フィールドにインデックスを使用すると、範囲スキャンも提供されます。

これ以上速くなることはありません。トリックや機能は必要ありません。

于 2012-08-14T17:53:23.570 に答える
0

日付に関しては、いくつかの考慮事項があります。

まず、関連するインデックスが確実に使用されるようにする必要があります。一般に、これは列の関数を回避することを意味します。これは日付以外のデータ型に適用されますが、日付を理解するための一般的な機能です。したがって、CONVERT() は、列にインデックスが付けられていると仮定すると、パフォーマンスの観点からは悪い考えです。

2 つ目は、フォーマット間の不要な変換を避けたい場合です。したがって、すべての行に対して関数の呼び出しが発生する必要があります。代わりに、定数文字列の日付/時刻への変換は、コンパイル時に 1 回行われます。1つ目は効率が悪い。CONVERT() を避けるもう 1 つの理由。ただし、多くのクエリでは、他の処理 (結合など) は変換よりもはるかに時間がかかるため、これは重要ではない場合があります。

「間」と符号付き操作の選択について。"<" と ">" と ">=" と "<=" を使用することをお勧めします。日付のロジックがより明確になり、秒が 3 ミリ秒の精度になるなどの問題はありません。

私の知る限り、日付の間は、他のタイプのフィールドと同じようにインデックスを使用して効率的に機能します。ただし、精度と移植性のためには、個々の比較を行うのが最善です。

したがって、3 番目のバージョンが優先されます。

于 2012-08-14T18:01:22.207 に答える