2017-10-18 3 views
0

コードベース全体で使用される流暢なSQLクエリビルダを持つC#アプリケーションコードを継承しました。より一般的なクエリの中には、「今日の日付または今日の日付」のようなフィルタを適用するものがあります。これらのフィルタは、クエリビルダのメタデータとしてSQLテーブルに格納され、パフォーマンスやデッドロックの問題を調査していますが、これらのクエリコンポーネントは使用できません。DateDiff()SQLクエリのSargableバージョン

このビルダによって構築された一般的なクエリは次のようになります

DECLARE @systemDate DATETIME 
SET @systemDate = [dbo].GetSystemDate() 

SELECT [table1].* FROM [dbo].[XXX] AS [table1] 
WHERE ... AND DateDiff(d, @systemDate, [table1].PaymentDate) <= 0 
AND ... 

列PaymentDateは、時間成分と、日時として記憶されます。 GetSystemDate()は真夜中の時刻を返します。つまり、2017-10-18 00:00:00.000

問題があるのは、カバリングインデックスでPaymentDateを持っていても、SQL ServerはそれをシークできませんDateDiff()関数で使用します。しかし、クエリビルダの設計は、すべての構築されたSQLクエリに適用される、より効率的で許容可能な式に置き換えることを非常に容易にします。

時間コンポーネントもクエリされた列で再生され、結果のクエリは既存のDateDiff()呼び出しに同じ結果を返す必要があるので、次の同等のsargableクエリはどのようになりますか?私はDateAdd()と比較を使用して他のソリューションを見てきましたが、私たちのデータに時間コンポーネントがあると仮定すると、これらの動作が異なることに注意しています。

OperatorDisplayName OperatorExpression ValueExpression ColumnExpression 
Today      =     0   DateDiff(d, @systemDate, {0}) 
This Week     =     0   DateDiff(ww, @systemDate, {0}) 
Last Week     =     -1   DateDiff(ww, @systemDate, {0}) 
This Month     =     0   DateDiff(m, @systemDate, {0}) 
Last Month     =     -1   DateDiff(m, @systemDate, {0}) 
On or Before Today   <=     0   DateDiff(d, @systemDate, {0}) 
On or After Today   >=     0   DateDiff(d, @systemDate, {0}) 
Before Today     <     0   DateDiff(d, @systemDate, {0}) 
After Today     >     0   DateDiff(d, @systemDate, {0}) 

答えて

0

@systemDateは時間コンポーネントを持たないので、あなたは> = <比較構築することができます:それはに組み込まれているので、あなたは本当に、このようオペレータまたは値を使用していない

OperatorDisplayName OperatorExpression ValueExpression ColumnExpression 
Today      =     0   {0} >= @systemDate AND {0} < DATEADD(d, 1, @systemDate) 

は、列式。

@systemDateに基づいて週/月の最初の日を計算するコードに式を含める必要があるため、週と月の演算子が複雑になりますが、すでにWeb上にサンプルがあります。

関連する問題