4


0

SQL DATEDIFF(year、…​、…​)は高価な計算ですか?

完了するのに時間がかかりすぎるため、恐ろしく複雑なSQLクエリを最適化しようとしています。

私のクエリでは、同じ関数がたくさんあるSQLステートメントを動的に作成したため、各関数が何度も何度も呼び出されるのではなく、1回だけ呼び出される一時テーブルを作成しました。これにより、実行時間が3/4短縮されました。

だから私の質問は、たとえば1,000のdatediff計算が100に絞り込まれた場合、多くの違いを期待できるでしょうか?

編集:クエリは次のようになります:

SELECT DISTINCT M.MID, M.RE FROM #TEMP INNER JOIN M ON #TEMP.MID=M.MID
WHERE ( #TEMP.Property1=1 ) AND
DATEDIFF( year, M.DOB, @date2 ) >= 15  AND  DATEDIFF( year, M.DOB, @date2 ) <= 17

これらは文字列として動的に生成され(ビットとピースにまとめられ)、実行されてさまざまなパラメーターが各反復-主にあらゆる種類のDATEDIFFクエリを含む最後の行に沿って変更できるように実行されます。

このような約420個のクエリがあり、これらのdatediffはそのように計算されています。 私はそれらをすべて簡単に一時テーブルにプルできることを知っています(1,000 datediffsは50になります)-しかし、それは価値があります、それは数秒で違いを生じますか? 10分の1秒よりも改善されることを望んでいます。

3 Answer


13


パフォーマンスヒットの範囲について正直に言うには、まさにあなたが何をしているかに依存します。

たとえば、WHERE句内でDATEDIFF(または他の関数)を使用している場合、その列でインデックスが使用されなくなるため、パフォーマンスが低下する原因になります。

e.g. 基本的な例、2009年にすべてのレコードを検索

WHERE DATEDIFF(yyyy, DateColumn, '2009-01-01') = 0

DateColumnのインデックスをうまく利用しません。 一方、より優れたソリューションとして、最適なインデックス使用を提供することは次のとおりです。

WHERE DateColumn >= '2009-01-01' AND DateColumn < '2010-01-01'

私がhttp://www.adathedev.co.uk/2010/02/optimising-date-filtered-sql-queries.html [最近ブログに掲載]の違いについて(パフォーマンスの統計/実行計画の比較で)再興味があります。

結果セットの列としてDATEDIFFを返すよりもコストがかかります。

まず、最も時間がかかっている個々のクエリを特定します。 実行計画を確認して、問題のある場所を確認し、そこから調整します。

*編集:*指定したクエリ例に基づいて、WHERE句内でのDATEDIFFの使用を削除するための方法を次に示します。 特定の日付に10歳だったすべての人を見つけるための基本的な例-数学は正しいと思いますが、とにかくアイデアは得られます! 簡単なテストを行い、問題ないようです。 あなたのシナリオに適応するのに十分簡単でなければなりません。 特定の日付で(たとえば)15歳から17歳までの人を見つけたい場合は、このアプローチでも可能です。

-- Assuming @Date2 is set to the date at which you want to calculate someone's age
DECLARE @AgeAtDate INTEGER
SET @AgeAtDate = 10

DECLARE @BornFrom DATETIME
DECLARE @BornUntil DATETIME
SELECT @BornFrom = DATEADD(yyyy, -(@AgeAtDate + 1), @Date2)
SELECT @BornUntil = DATEADD(yyyy, [email protected] , @Date2)

SELECT DOB
FROM YourTable
WHERE DOB > @BornFrom AND DOB <= @BornUntil

追加する重要な注意事項は、DOBの年齢計算用で、このアプローチはより正確です。 現在の実装では、実際の日ではなく、誕生年のみが考慮されます(例: 2009年12月1日に生まれた人は、2010年12月1日まで1歳ではなかった2010年1月1日に1歳として表示されます)。

お役に立てれば。


0


DATEDIFFは、文字列などの日時値を処理する他の方法と比較して非常に効率的です。 (https://stackoverflow.com/questions/133081/most-efficient-way-in-sql-server-to-get-date-from-datetime [このSOの回答を参照])。

この場合、同じデータを何度も繰り返しているように聞こえますが、一時テーブルを使用するよりもコストがかかる可能性があります。 たとえば、統計が生成されます。


0


パフォーマンスを改善するためにできることの1つは、MIDの一時テーブルにインデックスを配置することです。

実行計画をチェックして、それが役立つかどうかを確認します(一時テーブルの行数に依存する場合があります)。