为啥交叉应用比内连接快?
Posted
技术标签:
【中文标题】为啥交叉应用比内连接快?【英文标题】:Why cross apply is faster than inner join?为什么交叉应用比内连接快? 【发布时间】:2014-03-26 01:15:01 【问题描述】:我有以下功能:
FunctionA - returns Object ID and Detail ID
FunctionB - returns Detail ID and Detail Name
以下查询用于提取Object ID
、Detail ID
和Detail Name
:
SELECT FunctionA.ID
,FunctionA.DetailID
,FunctionB.DetailName
FROM FunctionA (...)
INNER JOIN FunctionB (...)
ON FunctionA.DetailID = FunctionB.DetailID
下面的截图显示了它的执行计划成本(需要 32 秒):
在以下查询中,我已将查询更改为使用cross apply
而不是inner join
,并使FunctionB
返回Detail Name
以获取特定的Detail ID
:
SELECT FunctionA.ID
,FunctionA.DetailID
,FunctionB.DetailName
FROM FunctionA (...)
CROSS APPLY FunctionB (FunctionA.DetailID)
ON FunctionA.DetailID = FunctionB.DetailID
下面的截图显示了它的执行计划成本(需要 3 秒):
在第一种情况下,FunctionB
返回所有对 Detail ID
和 Detail Name
,通常需要很长时间。
在第二种情况下,FunctionB
的执行速度更快,因为它只为特定的Detail ID
返回Detail Name
,但它会为每个Object ID
执行。
为什么第一种情况这么慢? SQL Server 是在第二种情况下为每一行执行FunctionB
,还是正在缓存结果并避免执行该函数
参数一样吗?
【问题讨论】:
能否请您以 .xml 格式发布执行计划。我在这里想两件事之一。 RBAR 是由 INNER JOIN 方法强制执行的。通过交叉应用,优化器有机会在认为合适的情况下进行不同的优化。我会冒险猜测执行计划并不相同,看看我们可以确定的那些。 只是出于好奇您使用的是哪个版本的 sql server?如果您使用 sql express 那么由于线程和内存限制,限制将导致上述情况。 @ChocoSmith 我正在使用SQL-SERVER-2012
- 检查问题标签
@gotqn *** 没有 sql-server-express-2012 的标签(仅适用于其他 express 版本)所以我很好奇你是否正在运行 express,因此问题和对线程的引用和内存限制。但是由于您正在运行非快递,因此这不是您要寻找的答案:)
@ChocoSmith 对不起,我没有正确理解你。
【参考方案1】:
我认为交叉应用有时会更快,因为它可以在实际连接完成之前限制要连接的行数,因此实际连接的行数较少。
在您的第二个示例中,从 FunctionB 返回的行数将少于连接整个表时的行数,因此实际连接会更快,总时间会更短。
表中有多少行数据,它们是否正确编入索引?
【讨论】:
【参考方案2】:CROSS APPLY 旨在与基于参数返回结果的函数和表一起使用。
所以,您查询函数的事实是“CROSS APPLY”更快的原因。
【讨论】:
以上是关于为啥交叉应用比内连接快?的主要内容,如果未能解决你的问题,请参考以下文章