SQL Server中内联表值的成本

时间:2009-08-19 16:42:57

标签: sql-server sql-server-2008

如果SQL直接内联,在SQL Server 2008中使用内联表值函数是否存在固有成本?我们的应用程序非常大量地使用内联表值函数来重用常见查询,但最近,我们发现如果我们不使用它们,查询运行得更快。

考虑一下:

CREATE FUNCTION dbo.fn_InnerQuery (@asOfDate DATETIME)
RETURNS TABLE
AS
RETURN
(
   SELECT ... -- common, complicated query here
)

现在,当我这样做时:

SELECT TOP 10 Amount FROM dbo.fn_InnerQuery(dbo.Date(2009,1,1)) ORDER BY Amount DESC

查询返回结果大约15秒。

然而,当我这样做时:

SELECT TOP 10 Amount FROM 
(
   SELECT ... -- inline the common, complicated query here
) inline
ORDER BY Amount DESC

查询返回时间不到1秒。

在这种情况下,我对使用表值函数的开销感到有些困惑。我没想到的是。我们的应用程序中有很多表值函数,所以我想知道这里是否有我遗漏的东西。

4 个答案:

答案 0 :(得分:3)

在这种情况下,UDF应该像视图一样被取消/扩展,它应该是透明的。

显然,它不是......

在这种情况下,我的猜测是该列是smalldatetime并且由于udf参数而被强制转换为datetime但是在内联时正确评估了常量(以匹配colum数据类型)。

datetime的优先级高于smalldatetime,因此该列将被强制转换

查询计划说了什么? UDF将显示扫描,内联搜索最有可能(不是100%,仅基于我之前看到的)

修改:Blog post by Adam Machanic

答案 1 :(得分:0)

可以减慢功能的一件事是省略dbo。来自函数内的表引用。这导致SQL Server对每个调用进行安全检查,这可能很昂贵。

答案 2 :(得分:0)

尝试独立运行表值函数以查看它执行的速度/速度有多快?

另外,我不确定如何清除执行缓存(?)SQL Server可能从执行UDF中保留的内容。我的意思是 - 如果你首先运行UDF,可能是SQL Server具有实际查询的情况。它可以缓存计划/结果。因此,如果您单独运行复杂的查询 - 它可以从缓存中运行它。

答案 3 :(得分:0)

在第二个示例中,Table Valued函数必须在查询可以应用过滤器之前返回整个数据集。跳过TF边界不是优化者可以做的事情。

在第三个示例中,查询优化器可以确定用户只需要前几个“金额”。如果这不是聚合值,则优化器可以将该处理权限推送到查询的开头,而不会打扰任何其他数据。如果它是一个总量,那么减速是出于另一个原因。

如果您比较两个查询的查询计划,您应该看到它们是不同的。