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,所以顺序确实很重要。也许解决方案是我应该使用外部应用,但是此问题之前未曾提出过。
答案 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) 并按其余列分组