Вони не рівноцінні. Записи, які були 7 днів тому, але до поточного часу доби , повертаються лише у запиті №2:
Порівнюючи дні за допомогою DATEADD
функції , вона не враховує часової частини . Функція поверне 1 при порівнянні неділі та понеділка, незалежно від часу.
Демонстрація:
DECLARE @MyTable TABLE(pk INT, LogInsertTime DATETIME);
INSERT @MyTable
VALUES (1, DATEADD(HOUR, 1, CAST(DATEADD(DAY, -7, CAST (GETDATE() AS DATE))AS DATETIME))),
(2, DATEADD(HOUR, 23, CAST(DATEADD(DAY, -7, CAST (GETDATE() AS DATE)) AS DATETIME)));
DECLARE @DateTime DATETIME = GETDATE();
SELECT *
FROM @MyTable
WHERE DATEDIFF(DAY, LogInsertTime, @DateTime) > 7;
-- 0 records.
SELECT *
FROM @MyTable
WHERE LogInsertTime < @DateTime - 7;
-- 1 record.
Логічний еквівалент першого запиту, який дозволить потенційному використанню індексу, це або видалити часову частину, @DateTime
або встановити час на 0:00:00
:
SELECT *
FROM @MyTable
WHERE LogInsertTime < CAST(@DateTime - 7 AS DATE);
Причина, по якій перший запит не може використовувати індекс, LogInsertTime
полягає в тому, що стовпець похований у функції. Запит №2 порівнює стовпець з постійним значенням, що дає можливість оптимізатору вибрати індекс на LogInsertTime
.
LogInsertTime
?