内联函数和视图之间的区别

Posted

技术标签:

【中文标题】内联函数和视图之间的区别【英文标题】:Difference between a inline function and a view 【发布时间】:2009-06-12 18:51:53 【问题描述】:

我是使用函数的新手,在我看来内联函数与视图非常相似。我说的对吗?

另外,我可以在函数中包含 UPDATE 语句吗?

【问题讨论】:

【参考方案1】:

在这里阅读了许多答案后,我想指出内联表值函数与任何其他类型的函数(标量或多行 TVF)之间存在很大差异。

内联 TVF 只是一个参数化视图。它可以像视图一样扩展和优化。在“返回结果”或类似的东西之前不需要具体化任何东西(尽管不幸的是,语法有一个RETURN

我发现内联 TVF 相对于视图的一大好处是它确实强制进行所需的参数化,而对于视图,您必须假设调用者将适当地加入或限制视图的使用。

例如,我们在 DW 中有许多带有典型 Kimball 星模型的大型事实表。我对以事实表为中心的模型有一个看法,它不受任何限制地调用,将返回数亿行。通过使用具有适当参数化的内联 TVF,用户不会意外请求所有行。两者的性能在很大程度上无法区分。

【讨论】:

【参考方案2】:

没有区别。它们都被扩展/取消嵌套到包含的查询中。

注意:索引视图被认为是不同的,但仍然可以扩展,多值表函数是包含查询的黑盒子。

Tony Rogerson: VIEWS - they offer no optimisation benefits; they are simply inline macros - use sparingly

Adam Machanic: Scalar functions, inlining, and performance: An entertaining title for a boring post

Related SO question: Does query plan optimizer works well with joined/filtered table-valued functions?

Scary DBA (at the end)

最后,函数中不允许写入表

编辑,在 Eric Z Beard 发表评论并投反对票后...

问题和答案(不仅仅是我的)与标量 udf 无关。 “内联”是指“内联表值函数”。非常不同的概念...

【讨论】:

函数不正确,Sql Server 不正确。函数是一个黑盒子,不会扩展到包含的查询中——这就是为什么如果你使用查询任何东西的函数,性能会很糟糕。它变成了一个糟糕的嵌套循环,因为该函数是针对每一行单独处理的。 @Eric:对于内联表值函数,我说的是正确的。我说多值 TVF 是黑匣子。问题和我的回答不涉及“标量 udfs”,它们是黑盒子。【参考方案3】:

更新: 看起来我错过了“内联”部分。但是,如果有人想了解 VIEW 和常规函数之间的区别,我将在此处留下答案。

如果您只有一个执行 SELECT 并输出数据的函数,那么它们是相似的。但是,即使那样,它们也不相同,因为引擎可以优化视图。例如,如果您运行 SELECT * FROM view1 WHERE x = 10;并且您在映射到 X 的表字段上有索引,那么它将被使用。另一方面,函数会在搜索之前构建一个结果集,因此您必须在其中移动 WHERE - 但是,这并不容易,因为您可能有很多列并且您不能在同一个 select 语句中对所有列进行排序。

因此,如果您比较视图和函数以完成对数据提供“视图”的相同任务,那么 VIEW 是更好的选择。

但是,函数可以做得更多。您可以执行多个查询,而无需使用 JOINS 或 UNION 连接表。您可以对结果进行一些复杂的计算,运行其他查询并将数据输出给用户。函数更像是能够返回数据集的存储过程,然后它们就像视图。

【讨论】:

【参考方案4】:

似乎没有人提到这方面。

您不能将Update 语句放入内联函数,但您可以编写Update 语句反对它们,就好像它们是可更新的视图一样。

【讨论】:

【参考方案5】:

一个很大的区别是函数可以接受参数,而 VIEW 不能。

我倾向于支持 VIEW,因为它是一种标准,因此是可移植的实现。当没有 WHERE 子句的等效 VIEW 将毫无意义时,我会使用函数。

例如,我有一个函数可以查询一个相对较大的有效时间状态表(“历史”表)。如果这是一个 VIEW 并且您尝试在没有 WHERE 子句的情况下查询它,您将获得大量公平的数据(最终!)使用一个函数建立一个合同,如果您想要数据,那么您必须提供一个客户 ID,一个开始日期和结束日期以及功能是我建立此联系的方式。为什么不是存储过程?好吧,我希望用户希望将结果集加入到更多数据(表、视图、函数等)中,并且函数是 IMO 执行此操作的最佳方式,而不是要求用户将结果集写入临时表。

【讨论】:

【参考方案6】:

回答您关于函数更新的问题 (msdn):

唯一可以通过以下方式进行的更改 函数中的语句是 对本地对象的更改 功能,例如本地游标或 变量。对数据库的修改 表,对游标的操作 不是函数本地的,发送 电子邮件,尝试编目 修改并生成结果 返回给用户的集合是 不能做的动作的例子 在函数中执行。

【讨论】:

【参考方案7】:

视图是从查询返回的数据的“视图”,几乎是一个伪表。函数返回通常从查询数据中派生的值/表。您可以在函数中运行任何 sql 语句,前提是该函数最终返回一个值/表。

【讨论】:

【参考方案8】:

函数允许您传入参数以创建更具体的视图。假设您想根据状态吸引客户。一个函数将允许您传入您正在寻找的状态,并按该状态为您提供所有客户。视图无法做到这一点。

【讨论】:

但是视图可以公开该状态,然后您可以使用 where 子句进行过滤。 确实如此。但是对于阅读代码的程序员来说,函数看起来更好。 Select * FROM CustomersByState('Iowa') 比 SELECT * FROM vCustomers WHERE State = 'Iowa' 更容易阅读。不过,这只是我的看法。【参考方案9】:

一个函数执行一个任务或许多任务。视图通过查询检索数据。适合该查询的内容也受到限制。在一个函数中,我可以更新、选择、创建表变量、删除一些数据、发送电子邮件、与我创建的 CLR 交互等等。比低级视图更强大!

【讨论】:

但您应该始终更喜欢视图而不是函数,以获得最佳性能和可移植性。

以上是关于内联函数和视图之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

视图和内联表函数之间是不是存在性能差异?

在 Render 函数 React js 中编写内联函数方法与普通方法之间的区别

内联函数与宏的区别

深入探讨 内联函数和宏定义的区别

内联函数和宏定义的区别和联系

39内联函数和宏定义的区别