TOP和外部申请

时间:2018-03-21 21:19:53

标签: sql-server sql-server-2012

如果我有这样的查询,那么OUTER APPLY只能应用于tblA的TOP 5行吗?或者它将应用于从tblA返回的所有行,并且只有那时TOP 5才适用?我在tblA中有很多行,我不希望OUTER APPLY在所有行上运行。

SELECT TOP 5 ACol1, ACol2, b.BCol2
FROM tblA
OUTER APPLY (SELECT TOP 1 BCol2 
             FROM tblB WHERE BCol1 = tblA.ACol1
             ORDER BY ins_dtim DESC) b
ORDER BY tblA.ACol3

2 个答案:

答案 0 :(得分:2)

首先,任何TOP没有匹配ORDER BY的使用很可能都是错误的。这适用于现有查询的两部分TOP 1 TOP 5语句。

对于这个问题,对于这个问题,你可能会更好:

SELECT TOP 5 ACol1, ACol2, MAX(b.BCol2) AS BCol2
FROM tblA a
LEFT JOIN tblB b ON b.BCol1 = a.ACol1
GROUP BY a.ACol1, a.ACol2

只要ACol1ACol2相当独特,它就应该与您拥有的一样有效。如果您的表中存在该数据,您现在拥有的内容可能允许重复的ACol1, ACol2对。这不会。但是,由于您不关心ORDER,只要它们与表中的实际数据匹配,您就没有理由抱怨如果返回不同的值。

但我理解这一切也可能是问题的简化版本,因此我将以两种方式直接解决问题。

首先,当您对行为不清楚时,正确的做法是检查执行计划。您不需要成为执行计划专家来确定发生了什么。如果您不熟悉每个节点的含义,Google可以帮助您理解它。

从另一方面来说,请不要引用我,但我希望Sql Server在这种特定情况下只使用它5次。我认为那是你希望听到的。 但在一般情况下不要指望它。

如果查询有ORDER BY子句,就像使用TOP时应该做的那样,那么在检查所有可能性之前,Sql Server无法知道返回哪些结果。此外,如果ORDER BY由APPLY结果中的任何字段确定,则Sql Server 肯定必须为每个可能的记录运行子查询。否则,它无法知道它需要哪些记录。

最后,在许多情况下,查询优化器会将APPLY处理为比JOIN更接近于子查询的内容。即使它似乎需要计算每条记录的结果,它仍然可能比你预期的要快。

答案 1 :(得分:0)

我发现OUTER APPLY将首先在所有行上完成,然后返回TOP 5.