【发布时间】: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 stackoverflow 没有 sql-server-express-2012 的标签(仅适用于其他 express 版本)所以我很好奇你是否正在运行 express,因此问题和对线程的引用和内存限制。但是由于您正在运行非快递,因此这不是您要寻找的答案:)
-
@ChocoSmith 对不起,我没有正确理解你。
标签: performance tsql sql-server-2012 inner-join cross-apply