TOP 5与OUTER APPLY执行顺序咨询:是否仅作用于tblA前5行?
关于OUTER APPLY与TOP执行顺序的问题
咱们直接说结论:你的原查询里,OUTER APPLY会先作用于tblA的所有行,之后再对关联后的完整结果集取TOP 5——这显然不是你想要的,毕竟tblA数据量庞大,这样会导致大量不必要的子查询执行。
为什么会这样?
SQL的逻辑执行顺序决定了这一点:
- 首先执行
FROM子句及其中的关联操作(包括OUTER APPLY这类逻辑等价于关联的操作),也就是对tblA的每一行,都要执行一次嵌套的SELECT TOP 1 BCol2子查询; - 等所有行都完成关联后,才会执行
ORDER BY tblA.ACol3,最后再取前5行。
这就意味着,哪怕你只需要最终的5条结果,原查询还是会遍历tblA的全部数据,触发N次(N=tblA总行数)子查询,性能开销会非常大。
怎么优化?
要让OUTER APPLY只作用于tblA的TOP 5行,你需要先筛选出tblA的目标行,再做关联。改写后的查询如下:
SELECT TOP 5 a.ACol1, a.ACol2, b.BCol2 FROM ( -- 先筛选出tblA按ACol3排序后的前5行 SELECT TOP 5 ACol1, ACol2, ACol3 FROM tblA ORDER BY ACol3 -- 这里必须排序,否则TOP的结果是不确定的 ) a OUTER APPLY ( SELECT TOP 1 BCol2 FROM tblB WHERE BCol1 = a.ACol1 ORDER BY ins_dtim DESC ) b ORDER BY a.ACol3
改写后的逻辑
- 子查询先对tblA按
ACol3排序,取出前5行,这一步只处理tblA的少量数据; - 然后对这5条筛选后的记录执行
OUTER APPLY,也就是只触发5次子查询; - 最后再排序(其实子查询已经排过了,这里可以省略,但保留也不影响)并取TOP 5,得到最终结果。
这样就能彻底避免遍历tblA的全部数据,完美解决你的性能顾虑。
内容的提问来源于stack exchange,提问作者Sandhya
相关产品推荐
相关产品推荐

