视图和内联表函数之间是不是存在性能差异?
Posted
技术标签:
【中文标题】视图和内联表函数之间是不是存在性能差异?【英文标题】:Are there performance differences between views and in-line table functions?视图和内联表函数之间是否存在性能差异? 【发布时间】:2018-01-30 22:03:55 【问题描述】:我目前在使用视图和内联表函数之间的设计决策之间犹豫不决,其中支持视图的论点是它是一个简单的SELECT
,但表函数的论点是一致性,因为我们在数据库中已经有数百个需要参数的对象,因此需要使用表函数。
假设我们有一个表 dbo.Data
、一个视图 dbo.vData
和一个内联表函数 dbo.tfData()
:
我们的场景是我们已经有几个表函数用于同一个表,就像dbo.tfDataFilterBy(parameter)
一样,所以在查询时保持一致性是一个明确的优势。性能是我们前进方向的一个重要因素。
新的视图和表格函数都只是做一个简单的SELECT * FROM dbo.Data
。我已经测试了一些基本的场景选择、连接和聚合,据我所知,执行计划是相同的。但是,是否有任何边缘情况可能会在两者之间产生不同的执行计划,可能有很多复杂的连接、子查询或我们可能会抛出的任何其他东西?
【问题讨论】:
视图和表值函数彼此之间有很大的不同。这有点像比较金枪鱼和西瓜。我会质疑为什么你想要一个不需要参数来返回正确数据的内联表值函数。如果查询真的只是一个简单的选择......为什么还要麻烦呢? @Lunyx 。 . .我会检查where
子句是否选择了基础索引。如果没有,那么我认为您不必担心太多。
@SeanLange 复杂性在于从哪个表中进行选择。当需要对表进行大量更新时,为了最大限度地减少锁定和脏读,我们创建另一个副本并在视图/函数中将它们换出。我已经解决了为什么在问题本身中考虑表函数。
仅仅因为您将表值函数用于其他事情应该与此完全无关。您应该使用对手头任务最有意义的结构。鉴于对您正在做什么的解释,从性能的角度来看,这听起来并没有太大的不同。
@SeanLange 我不同意。对于我们系统的某些最终用户,他们不一定有 SQL 背景,但在编写简单查询方面有非常基本的技能,保持一致肯定对他们有帮助。
【参考方案1】:
两者以不同的方式定义,但 sql 引擎以几乎相同的方式从基表构建它们。(因此您的执行计划相同)
请记住,视图实际上可以更新基础基表,因此请注意这种差异。
见:https://www.red-gate.com/simple-talk/sql/learn-sql-server/sql-view-basics/ 获取有关视图使用的一些有用信息。
如果您在应用程序中大量重复使用视图,则可以将其定义为索引视图。 SQL 服务器然后将视图具体化为一个表。当您对表进行更新时,这会在维护索引方面产生一些开销,但索引视图可以显着提高读取性能。此外,在企业版中,如果索引视图满足查询的要求,优化器可以使用索引视图,即使它没有被直接引用。
支持表函数的场合是您需要定期稍微更改表的定义,您不希望维护定义如此接近的多个视图。此外,表函数可以采用可在谓词中使用的参数来更改输出而不更改函数,对于视图,您需要使用不同的谓词定义不同的视图。
这些不是唯一的区别,但在决定使用哪个时可能是最有影响力的两个。
与性能更直接相关:执行计划应该没有太大差异,除非您使用的视图足以使优化器从定义中具体化表。
【讨论】:
其实附加的视图/表格功能不会有过滤器,所以不会有多个需要维护。看来我要读一篇好文章,以便乘火车回家。我没有意识到如果经常使用它会实现视图,但我不确定我能否想象它的表现会有很大不同,特别是如果它只是从表中直接选择的话。通过占用更多的数据库空间,这似乎可能是一个不利因素。 当然可以,但是如果您正在执行非常简单的查询,您应该能够直接执行它们而不会对您的表性能产生太大影响。当您需要抽象出一些复杂性以供重复使用时,这两个其他工具都适用。您还应该查看它们中的一个或两个是否处理锁定,我怀疑它们都可以定义为执行脏读或仅提交。 @user7396598 。 . .我不知道 SQL Server 根据执行频率来实现任何类型的视图具体化。您对此有任何文档参考吗? 它在答案中链接的文章中。直到我读到它,我才知道。 @user7396598,Joe Celko 并没有说 Microsoft SQL Server 将视图具体化为一种优化。他说“使用一个好的优化器,SQL 引擎可以决定有足够多的会话使用同一个 VIEW 并将其具体化为一个共享表”。这句话说的是理论而不是现实,因为他几十年来一直被孤立在象牙塔里:-)以上是关于视图和内联表函数之间是不是存在性能差异?的主要内容,如果未能解决你的问题,请参考以下文章
ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效
ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非 TOP、OFFSET 或 FOR XML