视图是否比简单查询更快?

时间:2009-01-13 14:09:03

标签: sql sql-server performance

select *  from myView

比查询本身更快地创建视图(为了拥有相同的resultSet):

select * from ([query to create same resultSet as myView])

如果视图使用某种缓存使其比简单查询更快,那么我并不完全清楚。

16 个答案:

答案 0 :(得分:581)

,视图可以分配聚集索引,当它们执行时,它们将存储可以加快结果查询的临时结果。

更新:至少有三个人对此投了反对票。尽管如此,我认为他们是错的;微软自己的文档清楚地表明,Views可以提高性能。

首先,简单的视图已经扩展到位,因此不直接有助于提高性能 - 这是真的。 但是,索引视图可以显着提高性能。

让我直接进入文档:

  

在视图上创建唯一的聚簇索引后,视图的结果集会立即生效并保存在数据库的物理存储中,从而节省了在执行时执行此高成本操作的开销。

其次,这些索引视图可以在中工作,即使它们没有被另一个查询直接引用,因为优化器会在适当时使用它们代替表引用。

再次,文档:

  

索引视图可以以两种方式用于查询执行。查询可以直接引用索引视图,或者更重要的是,如果查询优化器确定视图可以替换成本最低的查询计划中的部分或全部查询,则可以选择该视图。在第二种情况下,使用索引视图而不是基础表及其普通索引。查询中不需要引用视图,查询优化器在查询执行期间使用它。这允许现有应用程序从新创建的索引视图中受益,而无需更改这些应用程序。

可以找到此文档以及演示性能改进的图表here

更新2:答案受到了批评,因为它是提供性能优势的“索引”,而不是“视图”。但是,这很容易被驳斥。

我们说我们是一个小国的软件公司;我将以立陶宛为例。我们在全球销售软件并将我们的记录保存在SQL Server数据库中。我们非常成功,因此,在几年内,我们拥有1,000,000多条记录。但是,我们经常需要报告销售税,我们发现我们在本国只销售了100份软件。通过创建立陶宛记录的索引视图,我们可以在MS文档中描述的索引缓存中保留所需的记录。当我们在2008年运行立陶宛销售报告时,我们的查询将搜索深度仅为7的索引(Log2(100),其中包含一些未使用的叶子)。如果我们在没有VIEW的情况下做同样的事情而只依赖于表中的索引,我们必须遍历索引树,搜索深度为21!

显然,与单独使用索引相比,View本身将为我们提供性能优势(3倍)。我试图使用一个真实世界的例子,但你会注意到一个简单的立陶宛销售清单会给我们带来更大的优势。

请注意,我只是使用一个直的b树作为我的例子。虽然我相当确定SQL Server使用了一个b树的变种,但我不知道细节。尽管如此,这一点仍然存在。

更新3:关于索引视图是否仅使用基础表上的索引的问题已经出现。也就是说,换句话说:“索引视图只是标准索引的等价物,它不会为视图提供任何新的或独特的。”如果这是真的,当然,上面的分析是不正确的!让我提供Microsoft文档中的引用,该文档证明了我认为这种批评无效或无效的原因:

  

使用索引来提高查询性能并不是一个新概念;但是,索引视图提供了使用标准索引无法实现的额外性能优势。

再加上关于物理存储中数据持久性的上述引用以及关于如何在Views上创建索引的文档中的其他信息,我认为可以安全地说索引视图只是一个缓存的SQL选择碰巧使用主表上定义的索引。因此,我继续坚持这个答案。

答案 1 :(得分:41)

一般来说,没有。视图主要用于方便和安全,而不是用于提高速度。

也就是说,SQL Server 2000及更高版本确实有一个名为索引视图的特殊功能,可以大大提高性能,但您必须创建一个非常{的索引视图{3}}。

联机丛书中有关specific set of guidelines的重要参考资料。

以下文章介绍了view resolution

  

多年来,Microsoft®SQLServer™   已经支持创建的能力   虚拟表称为视图。   从历史上看,这些观点就是这些观点   主要目的:

     
      
  • 提供一种安全机制   将用户限制为某个子集   一个或多个基表中的数据。

  •   
  • 提供允许的机制   开发人员可以自定义用户的方式   逻辑上查看存储在base中的数据   表

  •   
     

使用SQL Server 2000,   SQL Server视图的功能是   扩展以提供系统性能   好处。有可能创建一个   视图上的唯一聚簇索引   以及非聚集索引   提高数据访问性能   最复杂的查询。在SQL Server中   2000年和2005年,有一个观点   引用了唯一聚簇索引   作为索引视图。

答案 2 :(得分:13)

编辑:我错了,你应该看到Marks answer above.

我不能用SQL Server的经验说话,但对于大多数数据库来说,答案是否定的。从性能上看,使用视图的唯一潜在好处是它可能会根据查询创建一些访问路径。但使用视图的主要原因是简化查询或标准化访问表中某些数据的方式。一般来说,您将无法获得性能优势。不过我可能错了。

我想出一个中等复杂的例子,并自己去看看。

答案 3 :(得分:13)

至少在SQL Server中,查询计划基于查询/视图参数存储在计划缓存中,用于视图和普通SQL查询。对于两者而言,当它们在未使用足够长的时间段时从缓存中删除,并且对于其他一些新提交的查询需要空间。之后,如果发出相同的查询,则重新编译它,并将计划放回缓存中。所以不,没有区别,因为您正在重复使用相同的SQL查询和具有相同频率的相同视图。

显然,一般来说,一个视图,就其本质而言(有人认为它经常被用来使它成为一个视图)通常比任何任意SQL语句都“重用”。

答案 4 :(得分:5)

如果您创建实体化视图(带有架构绑定的 )可能会更快。非物化视图的执行方式与常规查询类似。

答案 5 :(得分:4)

我的理解是,一段时间后,视图会更快,因为SQL Server可以存储执行计划,然后只使用它而不是试图在运行中找出一个。我认为现在的性能提升可能不像以前那么大,但我不得不猜测使用该视图会有一些微小的改进。

答案 6 :(得分:2)

我希望这两个查询的执行方式相同。视图只不过是存储的查询定义,没有视图的数据缓存或存储。当您运行它时,优化器将有效地将您的第一个查询转换为您的第二个查询。

答案 7 :(得分:2)

绝对一个视图比SQL Server的嵌套查询更好。在不知道为什么它更好的情况下(直到我阅读Mark Brittingham的帖子),我在运行一些测试时,在使用视图与嵌套查询时经历了几乎令人震惊的性能改进。在连续几百次运行查询的每个版本之后,查询的视图版本在一半的时间内完成。我会说这对我来说足够了。

答案 8 :(得分:0)

没有实际的区别,如果您阅读BOL,您会发现您的普通旧SQL SELECT * FROM X确实利用了计划缓存等。

答案 9 :(得分:0)

存储执行计划应该会有一些微不足道的好处,但它可以忽略不计。

答案 10 :(得分:0)

视图的目的是反复使用查询。为此,SQL Server,Oracle等通常会提供视图的“缓存”或“编译”版本,从而提高其性能。一般来说,这应该比“简单”查询更好,但如果查询真的非常简单,那么好处可以忽略不计。

现在,如果您正在进行复杂查询,请创建视图。

答案 11 :(得分:0)

在我的发现中,使用视图比普通查询快一点。我的stored procedure花费了大约25分钟(使用不同的更大记录集和多个联接)并且在使用视图(非群集)之后,性能稍微快一点但不重要。我不得不使用其他一些查询优化技术/方法来使其发生巨大变化。

答案 12 :(得分:0)

这一切都取决于具体情况。 MS SQL索引视图比普通视图或查询更快,但索引视图不能在环境镜像数据库(MS SQL)中使用。

任何类型循环中的视图都会导致严重减速,因为每次在循环中调用视图时都会重新填充视图。与查询相同。在这种情况下,使用#或@来保存数据循环的临时表比视图或查询更快。

所以这一切都取决于具体情况。

答案 13 :(得分:0)

从视图或表格中选择不会太有意义。

当然,如果View没有不必要的连接,字段等,您可以检查用于提高View性能的查询,连接和索引的执行计划。

您甚至可以在视图上创建索引,以获得更快的搜索要求。 http://technet.microsoft.com/en-us/library/cc917715.aspx

但是,如果您正在搜索'%...%',那么sql引擎将无法从文本列的索引中受益。如果您可以强制您的用户进行“...%”之类的搜索,那将会很快

在asp论坛上提到答案: https://forums.asp.net/t/1697933.aspx?Which+is+faster+when+using+SELECT+query+VIEW+or+Table+

答案 14 :(得分:0)

与所有期望相反,在某些情况下,视图的速度慢得多。

我最近在从Oracle提取的数据出现问题时需要发现这一点,需要将其处理为另一种格式。也许20k源行。一张小桌子。为此,我们将oracle数据尽可能不变地导入到表中,然后使用视图提取数据。 我们基于这些观点获得了次要观点。也许是3-4级的意见。

其中一个最终查询(可能提取了200行)最多需要45分钟!该查询基于一系列视图。也许深3-4级。

我可以使用每个有问题的视图,将其sql插入一个嵌套查询中,然后在几秒钟内执行它。

我们甚至发现我们甚至可以将每个视图写入临时表中并查询该视图以代替该视图,它仍然比仅使用嵌套视图快得多。

更奇怪的是,在我们达到将源行拖入数据库的限制之前,性能还不错,在几天的时间内性能就跌落了,只需要多几个源行

因此,使用从视图中拉出的查询比从嵌套视图中拉出的查询要慢得多,这对我来说毫无意义。

答案 15 :(得分:-2)

我遇到了这个话题,只是想分享来自Brent Ozar的帖子,作为使用可用性组时要考虑的事情。

Brent Ozar bug report