【发布时间】:2011-06-25 00:18:27
【问题描述】:
表值函数和视图有什么区别?有什么事情你可以用 1 做而另一个很难或不可能做吗?还是说效率上的区别?
【问题讨论】:
标签: sql-server sql-view sql-function
表值函数和视图有什么区别?有什么事情你可以用 1 做而另一个很难或不可能做吗?还是说效率上的区别?
【问题讨论】:
标签: sql-server sql-view sql-function
无参数的内联 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
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
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 类似。他们很可能不会被整体评估(甚至在某些情况下根本不会)or may be evaluated multiple times in others。多语句 TVF 将始终被评估并存储在返回表类型(基本上是一个表变量)中
【讨论】:
Is Updatable 是什么意思?
CREATE TABLE T(C INT);EXEC('CREATE FUNCTION F () RETURNS TABLE AS RETURN (SELECT * FROM T)');INSERT INTO F() VALUES(1);SELECT * FROM T;
with check option 和 VIEW_METADATA 的其他一些区别
在决定将我的SELECT 转换为VIEW 还是TVF 时,我通常有一个经验法则。
视图是否需要超过 2 秒才能完成? 超过 10,000 条记录?如果是,将其转换为 TVF。如果没有,请留下 一个人。
当然,这条规则纯粹是基于性能。
使用 TVF,我可以使用 CROSS APPLY,例如将其视为表格,但传递特定值,例如 主键。
WHERE ID = xxx,其中 'xxx' 是我在 SELECT 中传递的值。
性能更快!
如果我有 TVF 的视图,我将不得不允许视图带回超过 200 万行,只是为了在我的 SELECT 中返回不到 1% 的行。
想一想。
【讨论】:
我发现,当在函数的返回表上指定 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
【讨论】:
RETURNS 子句的函数不需要创建任何临时表,因此它的运行速度至少要快两倍。可能快很多,因为优化器可以将其查询包含在优化中