如果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秒。
在这种情况下,我对使用表值函数的开销感到有些困惑。我没想到的是。我们的应用程序中有很多表值函数,所以我想知道这里是否有我遗漏的东西。
答案 0 :(得分:3)
在这种情况下,UDF应该像视图一样被取消/扩展,它应该是透明的。
显然,它不是......
在这种情况下,我的猜测是该列是smalldatetime并且由于udf参数而被强制转换为datetime但是在内联时正确评估了常量(以匹配colum数据类型)。
datetime的优先级高于smalldatetime,因此该列将被强制转换
查询计划说了什么? UDF将显示扫描,内联搜索最有可能(不是100%,仅基于我之前看到的)
答案 1 :(得分:0)
可以减慢功能的一件事是省略dbo。来自函数内的表引用。这导致SQL Server对每个调用进行安全检查,这可能很昂贵。
答案 2 :(得分:0)
尝试独立运行表值函数以查看它执行的速度/速度有多快?
另外,我不确定如何清除执行缓存(?)SQL Server可能从执行UDF中保留的内容。我的意思是 - 如果你首先运行UDF,可能是SQL Server具有实际查询的情况。它可以缓存计划/结果。因此,如果您单独运行复杂的查询 - 它可以从缓存中运行它。
答案 3 :(得分:0)
在第二个示例中,Table Valued函数必须在查询可以应用过滤器之前返回整个数据集。跳过TF边界不是优化者可以做的事情。
在第三个示例中,查询优化器可以确定用户只需要前几个“金额”。如果这不是聚合值,则优化器可以将该处理权限推送到查询的开头,而不会打扰任何其他数据。如果它是一个总量,那么减速是出于另一个原因。
如果您比较两个查询的查询计划,您应该看到它们是不同的。