SQL不能在JOIN CTE之前进行ORDER BY。替代方案?

时间:2018-10-22 21:27:03

标签: sql sql-server sql-server-2012

SQL Server 2012,VS2015,SSMS 2017

我有一个查询,该查询当前正在使用OUTER APPLY,这正在减慢查询速度。我知道可以通过将OUTER APPLY更改为LEFT JOIN ON子句来加快速度,但是OUTER APPLY使用ORDER BY对表进行排序。 JOIN不允许我使用ORDER BY。是否有解决方法?

当前查询:

SELECT 
    t1.ItemID,
    ISNULL(DATEDIFF(s, t1.localTimeStamp, t3.localTimeStamp),
    DATEDIFF(s, t1.localTimeStamp, @End)) AS Duration, 
    t1.localTimeStamp AS TimeStamp
FROM 
    CTE1 AS t1
OUTER APPLY 
    (SELECT TOP 1 localTimeStamp
     FROM CTE1 AS t2
     WHERE t2.localTimeStamp > t1.localTimeStamp AND t2.ItemID = t1.ItemID
     ORDER BY t2.localTimeStamp ASC) AS t3

此查询从本质上讲是一个项目,并为单个项目计算表的条目之间的持续时间。源表是CTE1,其中包含具有多个ItemID,Values和localTimeStamps的行,这些行的顺序不特定。我也不能在ORDER BY子句中使用WITH CTE

新查询:

SELECT 
    t1.Value, t1.tName, t1.ItemID, 
    ISNULL(DATEDIFF(s, t1.localTimeStamp, t2.localTimeStamp),
    DATEDIFF(s, t1.localTimeStamp, @End)) AS Duration, 
    t1.localTimeStamp AS TimeStamp
FROM 
    CTE1 t1
LEFT JOIN 
    CTE1 t2 ON t2.localTimeStamp > t1.localTimeStamp AND t2.ItemID = t1.ItemID

问题在于,它将占用所有具有更大时间戳的行,而不仅仅是下一个(按localTimeStamp的顺序而不是实际行号)。

我可以让Join工作吗,还是有另一种方法可以使查询变慢呢?

(我知道联接速度更快,因为即使我联接的行多得多,第二个查询仍然比第一个查询好。)

由于我确定这将被标记为重复问题,所以我想指出,我在此网站上也阅读了许多其他类似的问题,并且每一个要求订购join子句的问题都在column1 = column2上进行连接,顺序无关紧要的地方,他们只是被误认为。因为我要加入column1> column2,所以顺序确实很重要。也许解决方案是我应该使用外部应用,但是此问题之前未曾提出过。

2 个答案:

答案 0 :(得分:3)

为什么不只使用lead()

SELECT tt.ItemID,
       COALESCE(DATEDIFF(second, t.localTimeStamp, LEAD(t.localTimeStamp) OVER (PARTITION BY t.ItemId ORDER BY t.localTimeStamp)),
                DATEDIFF(second, t.localTimeStamp, @End)
               ) as Duration, 
       t.localTimeStamp as TimeStamp
FROM CTE1 t;

Microsoft在优化APPLY方面做得很好。我猜想性能问题正在运行CTE两次,lead()应该解决。

答案 1 :(得分:0)

更改第二个查询以使用

Min(t2.localtimestamp) 并按其余列分组