2014-08-20 3 views
1

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

У меня есть следующий запрос:

;with base as 
(
SELECT Distinct 
    JobName 
    ,ActualStart as 'Start' 
    ,ActualDurationInSeconds as 'DurationInSeconds' 
    , right('0' + CONVERT(varchar(2), floor(ActualDurationInSeconds)/3600),2) 
    + ':' + right('0' + CONVERT(varchar(2), floor(ActualDurationInSeconds)/60%60) ,2) as 'DurationHrsMins' 
FROM JobStats 
WHERE JobName like 'WW%' 
) 

, Yesterday As 
(
    Select Distinct JobName, 
     Start, 
     DurationHrsMins, 
     DurationInSeconds 
    From base 
    Where Start >= CONVERT(DATE, GETDATE()-1) 
) 

, OneWeek as 
(
    Select JobName, 
    AVG(DurationInSeconds) as 'Avg' 
    From base 
    Where Start >= CONVERT(DATE, GETDATE()-7) 
    Group By JobName 
) 

, TwoWeek as 
(
    Select JobName, 
    AVG(DurationInSeconds) as 'Avg' 
    From base 
    Where Start >= CONVERT(DATE, GETDATE()-14) 
    Group By JobName 
) 
, Lifetime as 
(
    Select JobName, 
    AVG(DurationInSeconds) as 'Avg' 
    From base 
    Group By JobName 
) 
, Deviation as 
(
    Select JobName, 
    STDEV(durationInSeconds) as deviation 
    From base 
    Group by JobName 
) 

SELECT Distinct 
    Y.JobName, 
    Y.DurationHrsMins as 'CurrentDisplay', 
    Y.DurationInSeconds as 'CurrentDurationInSeconds', 
    right('0' + CONVERT(varchar(2), floor(W1.Avg)/3600),2) 
     + ':' + right('0' + CONVERT(varchar(2), floor(W1.Avg)/60%60) ,2) as 'OneWeekAvgDisplay', 
    W1.Avg as OneWeekDuration, 
    right('0' + CONVERT(varchar(2), floor(W2.Avg)/3600),2) 
     + ':' + right('0' + CONVERT(varchar(2), floor(W2.Avg)/60%60) ,2) as 'TwoWeekAvgDisplay', 
    W2.Avg as TwoWeekDuration, 
    right('0' + CONVERT(varchar(2), floor(L.Avg)/3600),2) 
     + ':' + right('0' + CONVERT(varchar(2), floor(L.Avg)/60%60) ,2) as 'LifetimeAvgDisplay', 
    L.Avg as LifeTimeDuration,  
    CASE 
    WHEN Y.DurationInSeconds > W1.Avg * 1.15 THEN 'RED' 
    WHEN Y.DurationInSeconds > W1.Avg * .8 THEN 'YELLOW' 
    WHEN Y.DurationInSeconds < W1.Avg THEN 'GREEN' 
    ELSE 'GREEN' 
    END as StopLight, 
    CONVERT(int,d.Deviation) 
FROM Yesterday Y 
JOIN OneWeek as W1 on W1.JobName = Y.JobName 
JOIN TwoWeek as W2 on W2.JobName = Y.JobName 
JOIN Lifetime as L on L.JobName = Y.JobName 
JOIN Deviation as D on d.JobName = Y.JobName 

Order By Y.JobName 

Теперь этот запрос работает великолепно, его бежит так быстро, что даже не регистрироваться в качестве 1 второго исполнения. ОДНАКО, если я дам CONVERT (int, d.Deviation) псевдоним, внезапно запрос теперь должен работать в течение минуты! WTF !?

Я рассмотрел оценочные планы действий, и они совершенно разные! Я нахожу это сумасшедшим, что предоставление псевдонима может иметь такое большое влияние.

Любые идеи о том, почему это может произойти?

Благодаря

EDIT:

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

ответ

0

Одна из причин, по которой запросы выполняются очень быстро, а затем внезапно заправляют ваш сервер после одного изменения, потому что кеш уже недействителен (по крайней мере, сервер так не считает). Я не могу найти конкретную документацию о том, как Common Table Expressions (CTE) взаимодействует с кешем, но я предполагаю, что изменение псевдонима заставляет сервер прекратить использование кеша и повторно обрабатывать ваши данные.

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

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

How can I clear the SQL Server query cache?

+0

Это не может быть кэш, так как он всегда будет работать медленно с псевдонимом, независимо от того, сколько раз я запустить его. Кроме того, если это кеш, объединение слияния не устранит проблему. – Limey

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