Является ли это условие сравнения дат SARG-совместимым в SQL?

Это состояние саргнину?

AND  DATEDIFF(month,p.PlayerStatusLastTransitionDate,@now) BETWEEN 1 AND 7)

Мое эмпирическое правило заключается в том, что функция слева делает условие не сарказуемым, но в некоторых местах я читал, что предложение BETWEEN саргенируемо. So does any one know for sure?

Для справки:

What makes a SQL statement sargable? http://en.wikipedia.org/wiki/Sargable

ПРИМЕЧАНИЕ. Если гуру заканчивается здесь, обновите страницу Sargable Wikipedia. Я немного обновил его, но я уверен, что его можно еще улучшить :)

Ответы на вопрос(2)

если мы посмотрим на эти два эквивалентных запроса:

SELECT OrderDate FROM Sales.SalesOrderHeader
WHERE DATEDIFF(month,OrderDate,GETDATE()) BETWEEN 1 AND 7;

SELECT OrderDate FROM Sales.SalesOrderHeader
WHERE OrderDate >= DATEADD(MONTH, -7, GETDATE())
  AND OrderDate <= DATEADD(MONTH, -1, GETDATE());

В обоих случаях мы видим сканирование кластерного индекса:

enter image description here

Но обратите внимание на рекомендуемый / отсутствующий индекс только в последнем запросе, поскольку он единственный, который может извлечь из этого пользу:

enter image description here

Если мы добавим индекс в столбец OrderDate, то снова запустим запросы:

CREATE INDEX dt ON Sales.SalesOrderHeader(OrderDate);
GO

SELECT OrderDate FROM Sales.SalesOrderHeader
WHERE DATEDIFF(month,OrderDate,GETDATE()) BETWEEN 1 AND 7;

SELECT OrderDate FROM Sales.SalesOrderHeader
WHERE OrderDate >= DATEADD(MONTH, -7, GETDATE())
  AND OrderDate <= DATEADD(MONTH, -1, GETDATE());

Мы видим большую разницу - последний использует поиск:

enter image description here

enter image description here

Обратите также внимание на то, насколько приблизительны оценки для вашей версии запроса. Это может быть абсолютно катастрофично для большого набора данных.

Очень мало случаев, когда функция или другое выражение, примененное к столбцу, будет пригодным для использования. Один известный мне случайCONVERT(DATE, datetime_column) - но эта конкретная оптимизация недокументирована, и я все равно рекомендую держаться от нее подальше. Не только потому, что вы неявно предполагаете, что использование функций / выражений для столбцов нормально (это не в любом другом сценарии), но и потому, чтоэто может привести к потерянным прочтениям и катастрофическим оценкам.

если бы это было саркастично. Один из вариантов может быть переписать его как:

WHERE p.PlayerStatusLastTransitionDate >= DATEADD(month,1,CAST(@now AS DATE))
AND   p.PlayerStatusLastTransitionDate <= DATEADD(month,7,CAST(@now AS DATE))

Который, я полагаю, будет саркастичным (хотя это и не так красиво).

ВАШ ОТВЕТ НА ВОПРОС