内联TVF的效果与观看次数


9

我有一个数据库,我在其中使用嵌入式TVF(表值函数)而不是视图。例如,我可能在TVF [fnCarBrands]内将两个称为[汽车模型]和[汽车制造商]的表连接在一起。

然后,其他TVF会调用这些TVF进行进一步的处理和报告。因此,我可以使用函数[fnCarBrands]并连接到表[购买年份]以形成函数[fnCarBrandHistory]。以此类推,用于多层TVF。

我可以使用视图获得相同的功能,因为我的内联TVF实际上只是表和其他TVF的连接。

用这种方式编写的嵌入式TVF的性能与视图相比如何?


您很可能会看到相同的执行计划和相同的性能。
AK 2012年

这就是我的想法,但是我被告知TVF的行为就像括号中的代数一样-它迫使DB引擎在优化之前首先完成该查询。有人告诉我,使用视图可以使优化器将整个查询作为一个单元进行优化。
FistOfFury 2012年

有点旁注,但是知道为什么要使用TVF代替视图吗?只是代码猴子数据猴子的方法可以解决问题?
Mark Storey-Smith

@ MarkStorey-Smith是的,原因就是您所说的代码猴子与数据猴子方法。
FistOfFury 2012年

Answers:


12

查询优化器将内联表值函数完全视为视图:

CREATE FUNCTION dbo.InlineUdf(@arg1 int)
RETURNS TABLE
AS
RETURN 
(
    ... your query here ...
);

一个多语句表值函数更像是一个存储过程运行。它们通常必须执行多次,而不是折叠到主查询中:

CREATE FUNCTION dbo.MultiStatementUdf (@col1 int)
RETURNS @result TABLE 
(
    id int primary key NOT NULL,
    ... 
)
AS
BEGIN
   DECLARE @var1 int
   set @var1 = 42

   INSERT @result
   SELECT ...
   RETURN
END;

1
@Andomar我的理解是多语句TVF像黑匣子一样运行,引擎不知道其中包含什么并且无法优化查询。您是否可以参考任何引用,说视图和嵌入式TVF是等效的?
FistOfFury 2012年

4

您需要为这些函数创建类似的视图,并查询每个视图以查看执行计划,以查看每个函数的运行情况。


究竟。基准测试,自己看看-这是学习的唯一可靠方法。
AK

@mrdenny是否无法预测优化器将如何处理每种类型的查询?当然,它遵循一些规则。
FistOfFury 2012年

2
@FistOfFury是的,有规则,成千上万条规则,与数百名开发人员多年的启发式代码相辅相成。这就是为什么您必须测试或要求Microsoft提供优化源代码的原因。
Mark Storey-Smith

如果您想了解数据库引擎如何确定该做什么,那么您需要阅读SQL Server Internals,amazon.com
s /…

3

当然,创建调用其他视图的视图也是性能的杀手。不要沿着那条路线走。编写您需要的查询,如果需要性能,请不要使用TVF或视图。造成问题的是分层,这在查询数据库时几乎总是一件坏事,而且您可能很快就达到了您可以引用的表数的限制,特别是因为您通常最终引用了不同层中的相同表。此外,虽然看起来好像更容易维护,但事实并非如此。当您需要修复的层位于底部时,由于新要求而尝试调试或添加列。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.