表值函数(TVF)与视图

Hao*_*est 75 sql-server sql-function sql-view

表值函数和视图之间有什么区别?是否有一些你可以做的事情,那是另一个很难或不可能做到的事情?或者差异在于效率?

Mar*_*ith 122

无参数内联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  
Run Code Online (Sandbox Code Playgroud)

内联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    
Run Code Online (Sandbox Code Playgroud)

多语种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    
Run Code Online (Sandbox Code Playgroud)

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

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

  • @RoyiNamir - 示例`CREATE TABLE T(C INT); EXEC('CREATE FUNCTION F()RETURNS TABLE AS RETURN(SELECT*FROM T)'); INSERT INTO F()VALUES(1); SELECT*FROM T;` (11认同)
  • 你是什​​么意思tvf`Is Updatable`? (3认同)
  • @RoyiNamir - 内联 TVF 可用于更新类似于视图的基表。 (2认同)

Fan*_*o68 6

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

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

当然,规则纯粹是基于性能

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

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

性能更快!

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

有什么要考虑的。