2010-01-20 3 views
7

Скажем, например, я присоединяюсь на столе номер, чтобы выполнить какую-то операцию между двумя датами в подзапросе, например:Как Dateadd влияет на производительность SQL-запроса?

select n 
     ,(select avg(col1) 
      from table1 
     where timestamp between dateadd(minute, 15*n, @ArbitraryDate) 
          and dateadd(minute, 15*(n+1), @ArbitraryDate)) 
    from numbers 
where n < 1200 

ли запрос работать лучше, если бы я, скажем, построил дату от конкатенации типа VARCHAR чем использовать функцию dateadd?

+0

n - это int (или smallint, whatever) поле в таблице1? –

+0

@Patrick Karcher, n - это int из таблицы [number]. – Daniel

+0

Возможно, вам нужно показать нам структуру таблицы 1 – HLGEM

ответ

4

Сохранение данных в формате даты и времени с использованием DATEADD, скорее всего, будет быстрее

Установите этот флажок вопрос: (! Не я) Most efficient way in SQL Server to get date from date+time?

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

+0

Это именно тот тип ответа, на который я надеялся. +1 для вас, чтобы найти его и +1 к Tomas для отличного теста. Благодаря! – Daniel

3

Я бы не пошел с конкатенацией varchars.

DateAdd будет лучше работать, чем перенос строк, и отбрасывать до DATETIME.

Как всегда, лучше всего было бы профилировать 2 варианта и определить лучший результат, так как не указано ни одной БД.

+0

В чем причина этого? – Daniel

4

Будьте осторожны с между и даты, посмотрите на How Does Between Work With Dates In SQL Server?

Я однажды optmized запроса для запуска из более чем 24 часов до 36 секунд. Просто не используйте функции даты или преобразования в столбце, см. Здесь: Only In A Database Can You Get 1000% + Improvement By Changing A Few Lines Of Code Чтобы узнать, какой запрос работает лучше, выполнить оба запроса и посмотреть планы выполнения, вы также можете использовать статистику io и время статистики, чтобы узнать, сколько чтение и время, затраченное на выполнение запросов

+0

Спасибо, что подняли «между».Я вижу, что у меня будет некоторое перекрытие. – Daniel

2

До тех пор, пока ваши вычисления предикатов не содержат ссылок на столбцы таблицы, которые вы запрашиваете, ваш подход не должен иметь значения в любом случае (для ясности).

Если вы должны были включить что-то из Table1 в расчет, я бы следил за сканированием таблиц или просмотром индексных индексов, поскольку он может больше не быть sargable.

В любом случае, проверьте (или отправьте)! execution plan для подтверждения.

2

Зачем вам когда-либо использовать коррелированный подзапрос? Это замедлит вас гораздо больше, чем дата. Они похожи на курсоры, они работают последовательно. Будет ли что-то вроде этой работы?

select n.n , avgcol1 
    from numbers n 
    left outer join 
     (
     select avg(col1) as avgcol1, n 
     from table1 
     where timestamp between dateadd(minute, 15*n, @ArbitraryDate) 
      and dateadd(minute, 15*(n+1), @ArbitraryDate) 
     Group by n 
     ) t 
    on n.n = t.n 
    where n < 1200 
+0

Это хорошая идея. Проблема в том, что таблица1 не перечислима (или обязательно перечислима). – Daniel

+0

Я пинаю себя за то, что не видел этого. Очень хорошая точка. –

+0

Я заменил внутреннее соединение левой внешней, так что этот запрос эквивалентен исходному. –

3

Скорее всего, не будет различий так или иначе. я запускаю это:

SET STATISTICS IO ON; 
SET STATISTICS TIME ON; 

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

+0

Спасибо за этот удобный совет – Daniel

Смежные вопросы