【问题标题】:What are the downsides of using SqlServer Views?使用 SqlServer 视图的缺点是什么?
【发布时间】:2011-05-04 12:19:00
【问题描述】:

使用 SqlServer 视图有什么缺点?

我经常创建视图以非规范化形式显示我的数据。

我发现查询这些连接之一比使用多个表之间的复杂连接生成复杂查询要容易得多,因此更快、更不容易出错并且更自我记录。特别是当我从不同角度分析相同的数据(许多相同的字段,相同的表连接)时。

但是创建和使用这些视图是否有成本?

我是否在减慢(或加快?)查询处理?

【问题讨论】:

  • +1 以我的经验,关于数据库视图的无知和错误信息令人难以置信。可能会有很多关于视图的作用和方式的讨论,但我不确定它们是否被这样框定以及答案是否显而易见。
  • @Mr Shoubs - 我认为人们在这里提出问题,即使答案很容易被谷歌搜索到,因为他们想要 SO 提供的交互性和跟进/问答,我认为我们不应该阻止这种情况.
  • 很公平,我已经重新回答了
  • @Mr Shoubs。也许有很多信息,但也可能是太多信息。我不想花 3 天时间阅读数百页的文档。我只想要一个简单的答案。
  • @Lill,不幸的是,我认为没有一个简单的答案:(

标签: sql-server tsql views performance


【解决方案1】:

说到视图,有优点也有缺点。

优点:

  1. 它们是虚拟表,不作为不同的对象存储在数据库中。存储的只是 SELECT 语句。
  2. 通过限制用户可以看到的内容,可以将其用作安全措施。
  3. 通过将常用的复杂查询封装到视图中,可以使它们更易于阅读。这是一把双刃剑 - 请参阅缺点 #3。

缺点:

  1. 它没有缓存优化的执行计划,因此它不会像存储过程那样快。
  2. 由于它基本上只是一个 SELECT 的抽象,它比执行纯 SELECT 稍慢。
  3. 它可以隐藏复杂性并导致陷阱。 (问题:ORDER BY 不兑现)。

我个人的意见是不要使用视图,而是使用存储过程,因为它们提供了视图的安全性和封装性,同时也提高了性能。

【讨论】:

  • 我认为最大的危险来自于缺点#3。隐藏的复杂性是潜在的危险。很多时候,使用视图的目的是“简化”,但从长远来看,它最终会产生更多问题。
  • 您能否解释一下 ORDER BY not Honored Gotcha 以及它是如何体现的。如果你想回答,我有一个问题。 stackoverflow.com/questions/5901558/…
【解决方案2】:

使用视图的一个可能缺点是您抽象了底层设计的复杂性,这可能导致初级开发人员和报告创建者滥用。

对于一个特别庞大和复杂的项目,我设计了一组视图,主要由报表设计人员使用来填充水晶报表。几周后我发现初级开发人员已经开始使用这些视图来获取聚合并加入这些已经很大的视图,仅仅是因为它们在那里并且易于使用。 (数据库中有很强的 EAV 设计元素。)在初级开发人员开始询问为什么看似简单的报告需要花费很多时间来执行时,我才发现了这一点。

【讨论】:

    【解决方案3】:

    视图的效率在很大程度上取决于基础表。该视图实际上只是一种查看查询结果的有组织的一致方式。如果用于形成视图的查询很好,并且在基础表上使用了适当的索引,那么视图不应该对性能产生负面影响。

    在 SQL Server 中,您还可以create materialized or indexed views(自 SQL Server 2000 起),这会稍微提高速度。

    【讨论】:

    • 一如既往,感谢未署名和未评论的反对票:P
    【解决方案4】:

    我也经常使用视图。然而,需要注意的一点是,如果您的基础表经常更改(尤其是在开发过程中),那么使用大量视图可能难以维护。

    编辑:话虽如此,我发现能够简化和重用复杂查询的便利和优势超过了维护问题,尤其是在负责任地使用视图的情况下。

    【讨论】:

      【解决方案5】:

      当视图包含最终查询未最终使用的逻辑、列、行或表时,视图可能会损害性能。我无法告诉你我看过多少次这样的东西:

      SELECT ... 
      FROM (View with complex UNION of ActiveCustomer and InactiveCustomer tables)
      WHERE Active = True 
      

      (从而从 InactiveCustomer 表中过滤掉视图中包含的所有行),或

      SELECT (one column)
      FROM (view that returns 50 columns)
      

      (SQL 必须检索大量数据,然后在后面的步骤中丢弃这些数据。可能那些其他列的检索成本很高,例如通过书签查找),或者

      SELECT ...
      FROM (view with complex filters)
      WHERE (entirely different filters)
      

      (如果直接查询表,SQL 可能会使用更合适的索引), 或

      SELECT (only fields from a single table)
      FROM (view that contains crazy complex joins)
      

      (通过连接产生的大量 CPU 开销,以及后来丢弃的表读取的不必要 IO),或者我最喜欢的:

      SELECT ...
      FROM (Crazy UNION of 12 tables each containing a month of data)
      WHERE OrderDate = @OrderDate
      

      (实际上只需要读取 1 个表时读取 12 个表)。

      大多数情况下,SQL 足够聪明,可以“看穿一切”并提出有效的查询计划。但在其他情况下(尤其是非常复杂的情况),它不能。在上述每种情况下,答案都是删除视图并改为查询基础表。

      至少(即使您认为 SQL 足够聪明,无论如何都可以优化它),消除视图有时可以使您自己的查询调试和优化更容易(更明显的是需要什么完成)。

      【讨论】:

      • 不确定问题出在哪里:SELECT ... FROM(查看活跃和非活跃客户的疯狂联合) WHERE Active = True 。您是说应该有另外两个视图,一个包含所有活跃客户,另一个包含非活跃客户。因此,如果您只需要活动,您可以查询“活动”视图等?
      • @Lill 好吧,在这个(人为的)示例中,视图组合了表中的数据,然后由最终查询过滤掉。所以直接查询 ActiveCustomer 表,完全绕过视图。
      • Re SELECT (one col) FROM (view with 50 cols) - 查看 SQL Server 2008 上的执行计划,这实际上已被优化掉。 SELECT (fields from single table) FROM (view with crazy complex joins) 也是如此 - 执行计划删除查询不需要的连接。
      【解决方案6】:

      我遇到的视图的一个缺点是在将它们合并到分布式查询中时性能会下降。这篇 SQLMag 文章讨论了 - 虽然我在演示中使用高度人工的数据,但我在“现实世界”中一次又一次地遇到这个问题。

      尊重你的意见,他们会善待你。

      【讨论】:

        【解决方案7】:

        SQL Server 中视图的各种限制是什么?

        观看次数的 11 大限制

        • 视图不支持 COUNT ();但是,它可以支持 COUNT_BIG ()
        • ORDER BY 子句在视图中不起作用
        • 当我们需要另一列时,常规查询或存储过程为我们提供了灵活性;我们可以立即向常规查询添加一列。如果我们想对视图做同样的事情,那么我们必须先修改它们
        • 在不经常使用的视图上创建索引
        • 创建视图后,如果基本表添加或删除了任何列,则在刷新之前通常不会反映在视图中
        • 索引视图中不允许进行 UNION 操作
        • 我们无法在嵌套视图情况下创建索引意味着我们无法在从另一个视图构建的视图上创建索引。
        • 索引视图中不允许自连接
        • 索引视图中不允许外部连接
        • 索引视图中不允许跨数据库查询

        来源SQL MVP Pinal Dave

        http://blog.sqlauthority.com/2010/10/03/sql-server-the-limitations-of-the-views-eleven-and-more/

        【讨论】:

          【解决方案8】:

          刚开始时,我总是认为视图会增加性能开销,但经验却是另一回事(视图机制本身的开销可以忽略不计)。

          这完全取决于底层查询是什么。查看索引视图 herehere ,最终你应该测试两种方式的性能以获得清晰的性能配置文件

          【讨论】:

          • 好吧,好吧,谈谈被人跳上去——我听起来比预期的要糟糕得多
          • @Mr Shoubs。也许有很多信息,但也可能是太多信息。我不想花 3 天时间阅读数百页的文档。我只想要一个简单的答案。我想我本可以要求一个很好的链接来回答这个问题。然后依靠得票最多的人。
          【解决方案9】:

          我最大的“抱怨”是 ORDER BY 在视图中不起作用。虽然这是有道理的,但如果没有预料到,它可能会跳起来咬人。正因为如此,在一些我以后无法指定 ORDER BY 的情况下,我不得不离开从使用视图切换到 SPROCS(它们自身有足够多的问题)。 (我希望有一个带有“FINAL VIEW”的结构——例如,可能包括 order by——语义)。

          http://blog.sqlauthority.com/2010/10/03/sql-server-the-limitations-of-the-views-eleven-and-more/(限制 #1 是关于 ORDER BY :-)

          【讨论】:

            【解决方案10】:

            以下是允许在视图中引用 order by 的 SQL hack:

            create view toto1 as 
            select top 99.9999 percent F1
            from Db1.dbo.T1 as a 
            order by 1
            

            但我更喜欢使用Row_Number:

            create view toto2 as 
            select *,  ROW_NUMBER() over (order by [F1]) as RowN from ( 
            select f1
            from Db1.dbo.T1) as a
            

            【讨论】:

              猜你喜欢
              • 2011-04-20
              • 1970-01-01
              • 1970-01-01
              • 2010-09-08
              • 2012-03-29
              • 1970-01-01
              • 1970-01-01
              • 2014-11-29
              • 2017-12-07
              相关资源
              最近更新 更多