Эффективность SQL — запрос с использованием функции dateAdd дважды; или подзапрос и функция DateAdd один раз; на дату МЕЖДУ

#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 считается «не подлежащим замене», и лучшее, что может сделать оптимизатор запросов, это выполнить полное сканирование индекса или таблицы.

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