表达式的列别名会减慢查询速度

时间:2014-08-20 13:55:22

标签: sql tsql

认为这真的很奇怪,所以我想我会发布它并看看人们的想法。

我有以下查询:

;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!?

我看了估计的提议计划,它们完全不同!我觉得这很疯狂,给别名可能会产生这么大的影响。

有关为何会出现这种情况的任何想法?

由于

编辑:

在Deviation上使用内部合并连接可以使用名称快速执行。

1 个答案:

答案 0 :(得分:0)

查询运行速度非常快,然后在单次更改后突然停止服务器的原因之一是因为缓存不再有效(至少服务器不这么认为)。我无法找到有关公用表表达式(CTE)如何与缓存交互的具体文档,但我猜测更改别名会导致服务器停止使用缓存并重新处理数据。

由于您已经开发了查询,因此测试此方法的一种方法是在运行每个查询之前删除缓存。我愿意打赌你的第一个查询需要比以前更长的时间,并且两者之间的运行时间几乎相同。

在你弄乱缓存之前,你会想要对它进行一些阅读。

How can I clear the SQL Server query cache?