Является ли SQL DATEDIFF (year, ..., ...) дорогостоящим вычислением? - PullRequest
4 голосов
/ 30 марта 2010

Я пытаюсь оптимизировать некоторые ужасно сложные запросы SQL, потому что это занимает слишком много времени для завершения.

В моих запросах я динамически создавал операторы SQL с множеством одинаковых функций, поэтому я создал временную таблицу, в которой каждая функция вызывается только один раз, а не много, много раз - это сократило мое время выполнения на 3/4.

Итак, мой вопрос: могу ли я ожидать значительных отличий, если, скажем, 1000 вычислений с датировкой сузятся до 100?

EDIT: Запрос выглядит так:

SELECT DISTINCT M.MID, M.RE FROM #TEMP INNER JOIN M ON #TEMP.MID=M.MID 
WHERE ( #TEMP.Property1=1 ) AND 
DATEDIFF( year, M.DOB, @date2 ) >= 15  AND  DATEDIFF( year, M.DOB, @date2 ) <= 17 

, где они генерируются динамически в виде строк (складываются в биты и куски) и затем выполняются, так что различные параметры могут быть изменены на каждой итерации - в основном, последние строки, содержащие все виды запросов DATEDIFF.

Существует около 420 запросов, подобных этим, где эти данные вычисляются следующим образом. Я знаю, что могу легко собрать их все во временную таблицу (1 000 датировок становится 50) - но стоит ли это, будет ли какая-то разница в секундах? Я надеюсь на улучшение лучше, чем за десятые доли секунды.

Ответы [ 3 ]

13 голосов
/ 30 марта 2010

От того, что вы делаете, зависит честность в отношении производительности.

Например, если вы используете DATEDIFF (или даже любую другую функцию) в предложении WHERE, это приведет к снижению производительности, поскольку не позволит использовать индекс для этого столбца.

например. базовый пример, поиск всех записей в 2009

WHERE DATEDIFF(yyyy, DateColumn, '2009-01-01') = 0

не будет использовать индекс DateColumn. Тогда как лучшее решение, обеспечивающее оптимальное использование индекса, будет:

WHERE DateColumn >= '2009-01-01' AND DateColumn < '2010-01-01'

Я недавно опубликовал в блоге информацию о том, какое это имеет значение (со статистикой производительности / сравнениями планов выполнения), если вам интересно.

Это было бы дороже, чем, скажем, возвращать DATEDIFF в качестве столбца в наборе результатов.

Я бы начал с определения отдельных запросов, которые занимают больше всего времени. Проверьте планы выполнения, чтобы увидеть, в чем заключается проблема, и настройтесь оттуда.

Edit: Основываясь на приведенном вами примере запроса, вот подход, который вы могли бы попробовать исключить использование DATEDIFF в предложении WHERE. Базовый пример, чтобы найти всех, кому было 10 лет на заданную дату - я думаю математика верна, но вы все равно поймете идею! Дали быстрый тест, и, кажется, в порядке. Должно быть достаточно легко адаптироваться к вашему сценарию. Если вы хотите найти людей в возрасте от 15 до 17 лет на определенную дату, это также возможно при таком подходе.

-- Assuming @Date2 is set to the date at which you want to calculate someone's age 
DECLARE @AgeAtDate INTEGER
SET @AgeAtDate = 10  

DECLARE @BornFrom DATETIME
DECLARE @BornUntil DATETIME
SELECT @BornFrom = DATEADD(yyyy, -(@AgeAtDate + 1), @Date2)
SELECT @BornUntil = DATEADD(yyyy, -@AgeAtDate , @Date2)

SELECT DOB
FROM YourTable
WHERE DOB > @BornFrom AND DOB <= @BornUntil

Важное замечание, которое необходимо добавить: для возрастных расчетов из DOB этот подход более точный Ваша текущая реализация учитывает только год рождения, а не фактический день (например, кто-то, родившийся 1 декабря 2009 года, будет показывать, что ему 1 год, 1 января 2010 года, если ему не 1 год до 1 декабря 2010 года).

Надеюсь, это поможет.

0 голосов
/ 30 марта 2010

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

Проверьте свой план выполнения, чтобы увидеть, помогает ли он (может зависеть от количества строк во временной таблице).

0 голосов
/ 30 марта 2010

DATEDIFF довольно эффективен по сравнению с другими методами обработки значений даты и времени, такими как строки. ( см. Этот SO-ответ ).

В этом случае звучит так, будто вы просматриваете одни и те же данные, что, вероятно, дороже, чем использование временной таблицы. Например, будет сгенерирована статистика.

...