コードベース全体で使用される流暢な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})