87

表值函数和视图有什么区别?有没有什么你可以用 1 做而另一个很难或不可能做的事情?或者区别在于效率?

4

3 回答 3

142

无参数的内联 TVF 和非物化视图非常相似。下面是一些浮现在脑海中的功能差异。

意见

Accepts Parameters               - No
Expanded out by Optimiser        - Yes
Can be Materialized in advance   - Yes (through indexed views)
Is Updatable                     - Yes 
Can contain Multiple Statements  - No
Can have triggers                - Yes
Can use side-effecting operator  - Yes  

内联 TVF

Accepts Parameters               - Yes
Expanded out by Optimiser        - Yes
Can be Materialized in advance   - No
Is Updatable                     - Yes
Can contain Multiple Statements  - No
Can have triggers                - No
Can use side-effecting operator  - No    

多语句 TVF

Accepts Parameters               - Yes
Expanded out by Optimiser        - No
Can be Materialized in advance   - No
Is Updatable                     - No
Can contain Multiple Statements  - Yes
Can have triggers                - No
Can use side-effecting operator  - No    

在运行时视图和内联 TVF 都是内联的,并且与派生表或 CTE 类似。它们很可能不会被整体评估(或者在某些情况下甚至根本不会被评估),或者可能会在其他情况下被多次评估。多语句 TVF 将始终被评估并存储在返回表类型中(基本上是一个表变量)

有时,直接参数化内联 TVF 的能力可以导致比针对视图的等效参数化查询更好的执行计划。

于 2011-02-10T17:23:16.100 回答
6

在决定将 my 转换为 a还是 a时,我通常有一个经验法则SELECTVIEWTVF

视图是否需要超过 2 秒才能完成并且是否有超过 10,000 条记录?如果是,将其转换为 TVF。如果没有,请不要理会它。

当然,这条规则纯粹是基于性能的。

使用 TVF,我可以使用CROSS APPLY, 例如将其视为表,但传递特定值,例如主键

WHERE ID = xxx,其中 'xxx' 是我在 SELECT 中传递的值。

性能更快!

如果我有一个 TVF 的视图,我将不得不允许视图带回超过 200 万行,只是为了在我的 SELECT 中返回不到 1% 的行。

需要考虑的事情。

于 2019-11-21T00:11:04.507 回答
2

我发现,当在函数的返回表上指定 PK 时,与 MultiStatement TVF 的连接性能比视图好得多。

CREATE FUNCTION [FORMREQS].[fnGetFormsStatus] ()
RETURNS

/* Create a PK using two of the columns */
@Indexed TABLE (
    [OrgID] [char](8) NOT NULL,
    [PkgID] [int] NOT NULL,
    [FormID] varchar(5) NOT NULL,
    PRIMARY KEY CLUSTERED(OrgID, PkgID) 
)
AS
BEGIN
INSERT @Indexed SELECT OrgID, PkgID, FormID FROM FormsTable

RETURN

END
于 2015-05-29T16:40:02.147 回答