4

完了するのに時間がかかりすぎるため、非常に複雑な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クエリを含む最後の行です。

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

4

3 に答える 3

13

パフォーマンスへの影響の程度について正直に言うと、正確に何をしているかによって異なります。

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

たとえば、基本的な例、2009年のすべてのレコードの検索

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

DateColumnのインデックスをうまく利用しません。より良い解決策は、最適なインデックスの使用法を提供することです。

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

興味があれば、最近、これがもたらす違いについてブログに書きました(パフォーマンス統計/実行プランの比較を使用)。

これは、結果セットの列として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, -@AgeAtDate , @Date2)

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

追加する重要な注意点は、生年月日からの年齢計算の場合、このアプローチはより正確です。現在の実装では、実際の日ではなく、生年月日のみが考慮されます(たとえば、2009年12月1日に生まれた人は、2010年12月1日まで1歳でない場合、2010年1月1日に1歳であると表示されます)。

お役に立てれば。

于 2010-03-30T17:49:29.037 に答える
0

パフォーマンスを向上させるためにできることの1つは、MIDの一時テーブルにインデックスを作成することです。

実行プランをチェックして、それが役立つかどうかを確認します(一時テーブルの行数によって異なる場合があります)。

于 2010-03-30T19:19:17.763 に答える
0

DATEDIFFは、文字列など、日時値を処理する他の方法と比較して非常に効率的です。(このSOの回答を参照してください)。

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

于 2010-03-30T17:56:05.107 に答える