我有以下功能:
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 Name
返回Detail ID
,但会为每个Object ID
执行。{/ p>
为什么第一种情况如此慢? SQL Server是否在第二种情况下为每一行执行FunctionB
,或者它是缓存结果并避免执行该函数
用相同的参数?
答案 0 :(得分:2)
我认为交叉应用有时会更快,因为它可以在实际连接完成之前限制要连接的行数,因此实际连接的行数会更少。
在第二个示例中,从FunctionB返回的行数将少于连接整个表时的行数,因此实际连接将更快,总时间将更短。
表格中有多少行数据,是否正确编入索引?
答案 1 :(得分:2)
CROSS APPLY用于与基于参数返回结果的函数和表一起使用。
因此,您查询功能的事实是“CROSS APPLY”更快的原因。