#sql #sql-server #performance #tsql
#sql #sql-сервер #Производительность #tsql
Вопрос:
Расход заключается в использовании функции DateAdd не только в SELECT, но и в WHERE; Или с использованием подзапроса, который изначально возвращает больше данных, чем мне нужно, но затем может быть отфильтрован без повторного использования функции DateAdd в базе данных.
План выполнения, похоже, подразумевает, что они идентичны, насколько это касается. Мне интересно, что было бы более эффективным?
DECLARE @DateFrom DateTime
SET @DateFrom = '2011-05-27'
DECLARE @DateTo DateTime
SET @DateTo = '2011-06-27'
SELECT id, name,
dateAdd(hour, datediff(hour, getdate(), getutcdate()), --UTC offset
dateadd(second, itsm_requiredbyx, '1/1/1970 12:00 AM')) as itsm_requiredbyx
FROM tablename
WHERE dateAdd(hour, datediff(hour, getdate(), getutcdate()), --UTC offset
dateadd(second, itsm_requiredbyx, '1/1/1970 12:00 AM'))
BETWEEN @DateFrom AND @DateTo
ORDER BY itsm_requiredbyx desc
---------------------------------------------------------------------------------------------
SELECT *
FROM
(
select id, name,
dateAdd(hour, datediff(hour, getdate(), getutcdate()), --UTC offset
dateadd(second, itsm_requiredbyx, '1/1/1970 12:00 AM')) as itsm_requiredbyx
from tablename
) RR
WHERE itsm_requiredbyx BETWEEN @DateFrom AND @DateTo
ORDER BY itsm_requiredbyx desc
Комментарии:
1. Я не думаю, что это имеет значение. Но это показывает, что вы выполняете вычисления для поля
itsm_requiredbyx
, а затем проверяете, находится ли результат между двумя внешними значениями,@DateFrom
и@DateTo
. Если вы не выполняете никаких вычислений для поля, но вместо этого выполняете (обратные) вычисления для внешних значений, а затем проверяете, находится лиitsm_requiredbyx
между этими двумя вычисленными значениями, запрос может использовать индексitsm_requiredbyx
.2. Существуют локали со смещением от UTC, которое не составляет целого числа часов. Поскольку вы, похоже, пытаетесь написать международный код, возможно, вам нужно знать об этом.
Ответ №1:
Я не думаю, что имеет значение, какой из двух вы используете. И согласованными планами выполнения.
Но, похоже, вы выполняете вычисления для столбца itsm_requiredbyx
, а затем проверяете, находится ли результат между двумя внешними значениями, @DateFrom
и @DateTo
. Таким образом, все даты из этого поля обрабатываются функциями до того, как WHERE
условия могут быть применены и индекс не может быть использован. Вторая ссылка (десять распространенных ошибок программирования SQL) в ответе @DOK предоставляет более подробную информацию о том, почему и когда это происходит.
Если вы не выполняете никаких вычислений для столбца, но вместо этого выполняете (обратные) вычисления для внешних значений, а затем проверяете, находится ли itsm_requiredbyx
между этими двумя вычисляемыми значениями, запрос может использовать индекс itsm_requiredbyx
(и функции будут вызываться только дважды, а не для каждой строки в таблице).
Ответ №2:
Эта статья может помочь вам выбрать. Если ваши столбцы date проиндексированы, может быть большая разница между используемыми методами, особенно в предложении WHERE.
Как говорится,
Если вы ищете большие таблицы с большим количеством записей, вы, скорее всего, будете индексировать некоторые столбцы даты, которые обычно используются для ограничения запросов. Когда столбец даты используется в предложении WHERE, оптимизатор запросов не будет использовать индекс, если столбец даты заключен в функцию.
Это также объясняется в Десяти распространенных ошибках программирования SQL, особенно в функциях # 2 для индексированных столбцов в предикатах:
Проблема возникает из-за того, что столбцы индекса передаются функции, которую механизм запросов должен затем вычислять для каждой отдельной строки в таблице. В подобных случаях предикат предложения WHERE считается «не подлежащим замене», и лучшее, что может сделать оптимизатор запросов, это выполнить полное сканирование индекса или таблицы.
Чтобы убедиться, что индексы используются, нам нужно избегать использования функций в индексированных столбцах.