【问题标题】:Views in SQL Server 2012 and laterSQL Server 2012 及更高版本中的视图
【发布时间】:2018-02-21 11:47:16
【问题描述】:

我想询问在 SQL 2012 及更高版本中使用视图时的性能。假设我有一个涉及多个连接等的复杂查询。假设由于查询的复杂性和记录的数量,这个查询需要 10 分钟才能执行。

我希望为最终用户提供一个简单的“表格”来使用,因此我选择使用上面的查询创建一个视图。我喜欢使用视图的概念,因为据我了解,您不会复制数据,而是创建一个“虚拟表”,它只是引用存储数据的位置。与使用相关数据创建第二个物理表相比,这显然是有效的。但我担心性能。

如果用户希望使用视图选择此数据的子集,是否需要先运行整个查询来创建视图,然后从该视图中提取所需数据的子集?换句话说,对于最终用户来说,他们会花 10 多分钟的时间来获取他们需要的数据吗?

【问题讨论】:

  • 这完全取决于视图。从简单的视图来看,逻辑处理的顺序不太可能改变,但这也意味着视图上的WHERE子句可能会导致语句运行得更快;由于大量数据被过滤。对于编写不佳或复杂的视图,逻辑处理的顺序可能会发生变化,这意味着可能必须首先解析查询的某些部分(而那些是缓慢的部分)。这也不意味着复杂的 View 不能快(或简单的慢)。找出答案的最好方法是测试。

标签: sql sql-server sql-server-2012 sql-server-2014 sql-server-2016


【解决方案1】:

引用视图的查询“作为一个整体”进行了优化,没有真正的痕迹表明曾经涉及过任何视图。

如果优化器做得很好,它不会先计算视图的结果然后过滤它——如果可能的话,它将把谓词推到很远的地方,“内部”视图和基表。

另一种思考方式,而不是“虚拟表”,而是作为“子查询宏” - 在优化发生之前有效地将子查询插入到引用查询中,就像宏可以在其他编译和优化之前的编程语言。

【讨论】:

    【解决方案2】:

    这取决于您对视图所做的操作。如果最终用户创建了一个影响 基于表达式的列的 where 子句,例如转换为不同的数据类型或案例逻辑以更改列值,整个视图需要在过滤谓词应用之前实现。这会大大减慢查询处理速度。

    如果最终用户性能是一个重要问题并且基础数据不经常更改,您可以在视图上放置一个索引。每当基础表内容发生变化时,SQL Server 都会执行视图并将结果存储在索引中。针对视图的查询将使用索引而不是再次执行视图的定义。您必须支付视图结果集的存储成本,但这是提高相对静态数据性能的有效方法。

    但是,我首先要研究的是为什么查询需要 10 分钟才能执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      • 2015-04-19
      • 1970-01-01
      • 2015-08-27
      相关资源
      最近更新 更多