繁体   English   中英

表达式的列别名使查询变慢

[英]column alias for expression slows query

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

我有以下查询:

;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上使用内部合并联接可以快速执行该名称。

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

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

不过,在弄乱缓存之前,您需要对此进行一些阅读。

如何清除SQL Server查询缓存?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM