视图比简单查询快吗?


357

是一个

select *  from myView

创建视图的速度比查询本身快(以便具有相同的resultSet):

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

对于视图来说,是否使用某种类型的缓存使其比简单查询更快,这对我来说还不是很清楚。


7
我不确定一个视图,但是嵌套视图就是整体性能。
Muflix

Answers:


678

是的,可以为视图分配聚簇索引,并且在这样做时,它们将存储临时结果,这些结果可以加快结果查询的速度。

更新:至少三个人对我投了反对票。出于所有应有的尊重,我认为它们是错误的。Microsoft自己的文档非常清楚地表明Views可以提高性能。

首先,将简单的视图扩展到适当的位置,因此不会直接有助于提高性能-确实如此。 但是,索引视图可以大大提高性能。

让我直接转到文档:

在视图上创建唯一的聚集索引后,视图的结果集将立即实现并保存在数据库的物理存储中,从而节省了在执行时执行此昂贵操作的开销。

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

同样,文档:

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

可以在此处找到本文档以及演示性能改进的图表。

更新2:批评该答案的依据是,提供性能优势的是“索引”,而不是“视图”。但是,这很容易被驳斥。

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

显然,与单独使用索引相比,视图本身将为我们提供3倍的性能优势。我尝试使用一个真实的示例,但您会注意到,立陶宛销售的简单清单将为我们提供更大的优势。

请注意,我只是在示例中使用直的b树。虽然我相当确定SQL Server使用了b树的某种变体,但我不知道细节。尽管如此,这一点仍然成立。

更新3:关于索引视图是否仅使用放置在基础表上的索引的问题已经提出。也就是说,换句话说:“索引视图仅相当于标准索引,它对视图没有提供任何新的或唯一的。” 当然,如果这是真的,那么以上分析将是错误的!让我提供Microsoft文档中的一句话,以说明为什么我认为这种批评无效或正确:

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

有关于物理存储和有关指标是如何在视图中创建的文档中的其他信息数据的持久以上报价在一起,我认为这是肯定地说,索引视图是不是只是一个缓存的SQL选择恰好使用主表上定义的索引。因此,我继续支持这个答案。


28
是的,索引视图可以大大提高性能。但是索引视图不仅是“视图”,而且通常来说,正常的“视图”并不比其关联的查询快。
2009年

10
@Charles-没关系是索引,视图可以利用索引而原始查询不能满足要求
annakata

193
/ applaud @Mark坚持自己的立场并合理地争论了这一点
annakata

17
哦,老兄,我已经为此投票了8次!我感到惊讶的是,人们会如此之快地投票,而至少没有Charles勇于提出自己的观点。
Mark Brittingham,2009年

8
由于一个表只能有一个clusterdee索引,并且您可以在视图上创建一个单独的聚簇索引,(因为聚簇索引中的字段是独立保存在索引页中的),因此这是一种作弊手段(work-arounnd?),允许您在一个表上获得两个聚簇索引。
2009年

50

一般来说,没有。视图主要用于便利和安全,不会(单独)带来任何速度上的好处。

也就是说,SQL Server 2000及更高版本确实具有称为索引视图的功能,该功能可以大大提高性能,但有一些警告:

  1. 并非所有视图都可以编入索引视图。他们必须遵循特定的一套准则,其中(除其他限制),意味着你不能包括常见的查询元素,比如COUNTMINMAX,或TOP
  2. 索引视图使用数据库中的物理空间,就像表上的索引一样。

本文介绍了索引视图的其他优点和限制

您可以…

  • 视图定义可以引用同一数据库中的一个或多个表。
  • 一旦创建了唯一的聚集索引,就可以针对视图创建其他非聚集索引。
  • 您可以更新基础表中的数据-包括插入,更新,删除,甚至是截断。

你不能...

  • 视图定义不能引用其他视图或其他数据库中的表。
  • 它不能包含COUNT,MIN,MAX,TOP,外部联接或其他一些关键字或元素。
  • 您不能修改基础表和列。该视图是使用WITH SCHEMABINDING选项创建的。
  • 您无法始终预测查询优化器将执行的操作。如果您使用的是Enterprise Edition,它将自动将唯一的聚集索引视为查询的选项–但是,如果找到“更好”的索引,则会使用该索引。您可以通过WITH NOEXPAND提示来强制优化器使用索引-但在使用任何提示时请保持谨慎。

3
完全不同意...从视图读取允许重写SQL ..通常,从视图读取(比从视图转储读取)更快。
亚伦·肯普夫

@AaronKempf,我很乐意看到一些参考,但这并不是我的经验。当我搜索“查看重写的SQL”时,得到的所有结果均参考Oracle,而不是SQL Server,例如docs.oracle.com/cd/E14072_01/server.112/e10810/qrbasic.htm
BradC

昨天我只是在做一些基准测试,我很惊讶..基本上,如果我从视图(到表)中进行转储,则我运行的任何查询都是更慢的..因为大多数查询都像黄油一样通过了视图并被重写由查询优化器..至少这就是我的假设。我将尝试在其上很快写一个博客条目,基准测试相当有趣。.基本上,视图可以极大地提高性能。
亚伦·肯普夫

@AaronKempf不确定与原始问题是否相同(关于查询还是将相同的查询放在视图中)。无论如何,除非您的新表没有好的索引,否则我看不到将视图具体化为表的方式会使它变慢(这正是索引视图的作用)。
2013年

1
布拉德 我写了一篇非常糟糕的博客文章,内容涉及在这种情况下视图如何为我节省了99%的性能。.我计划编写其他几篇文章,但是我知道我需要对此进行详细介绍。 。您介意看一下并告诉我您对我的描述的看法吗?我知道这没有什么意义(直到我再发表其他2-3篇文章)..但是我非常热衷于观点,而且我已经有很长时间了! accessadp.com/2013/01/22/do-views-increase-performance
亚伦·肯普夫

14

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

显然,通常来说,视图的本质是自然的(有人认为应该经常使用它以使其成为视图),而不是任意的SQL语句通常更可能被“重用”。


14

编辑:我错了,你应该看到马克斯回答上面。

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

我想出一个稍微复杂些的示例,自己动手看一下。


1
视图的另一个原因是在基于角色的模型中辅助访问控制
annakata

1
您对性能改进是错误的。我在最初的评论中没有做出足够的解释来说服某些人,但是MS拥有关于如何使用视图来改善性能的明确文档。请参阅下面的我(现在已被否决)的回复。
Mark Brittingham 2009年

7

如果创建实例化视图(具有模式绑定),则可能会更快。非实例化视图的执行与常规查询一样。


schemabinding与性能无关,它将视图的模式绑定到基础表,因此它保持同步,并且是索引视图的先决条件。
Sam Saffron

5

我的理解是,前一阵子,视图会更快,因为SQL Server可以存储一个执行计划,然后仅使用它而不是试图动态地制定一个计划。我认为如今的性能提升可能不如从前,但我不得不猜测使用该视图会有一些边际改进。


这是我的理解:以前很重要,不再
有用

从性能的角度来看,这不是访问限制。但这将是另一个话题。;)
AnonJr

哦,可以肯定,有很多充分的理由要使用视图,而不是一个人可以使用原始查询:P
annakata

4

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


感谢约旦...很高兴听到所有这些理论都在现实世界中得以解决。
Mark Brittingham

我对嵌套视图(视图中的视图)有经验,并且性能很差。当所有视图都重写为子选择时,性能要快很多倍,因此也许可以进行一些严格的测试。
Muflix '17

2

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


如果视图是一小组字段,然后用索引覆盖这些字段,SQL Server是否足够聪明,可以在执行第二种查询形式时使用该覆盖索引?
AnthonyWJones

1

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

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

因此,这完全取决于情况。


0

没有实际的不同,如果您阅读了BOL,您会发现以前的普通SQL SELECT * FROM X确实利用了计划缓存等优势。



0

视图的目的是一遍又一遍地使用查询。为此,SQL Server,Oracle等通常会提供视图的“缓存”或“编译”版本,从而提高其性能。通常,此查询应比“简单”查询更好,尽管如果查询确实非常简单,则好处可能微不足道。

现在,如果您要执行复杂的查询,请创建视图。


0

在我的发现中,使用视图比普通查询快一点。我的存储过程大约需要25分钟(使用其他较大的记录集和多个联接),并且使用视图(非集群)后,性能只是提高了一点点,但一点都不重要。我不得不使用其他一些查询优化技术/方法来使它发生巨大的变化。


我们如何编写/设计查询非常重要。
2011年

我发现使用CTE来限制从表返回的数据,然后执行所有工作/联接等工作,在许多情况下,CTE的性能都得到了显着改善
MattE

0

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

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

您甚至可以在视图上创建索引,以加快搜索需求。http://technet.microsoft.com/zh-CN/library/cc917715.aspx

但是,如果您要像'%...%'一样进行搜索,则sql引擎将无法从文本列索引中受益。如果您可以强迫用户进行“ ...%”之类的搜索,那将很快

提到在ASP论坛上的答案:https : //forums.asp.net/t/1697933.aspx?哪个+更快+何时+何时+使用+ SELECT + query + VIEW +或+ Table +


0

出乎所有人的意料,在某些情况下,视图的速度变慢了。

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

最后的查询之一可能提取了200行,最多需要45分钟!该查询基于一系列视图。可能是3-4级深。

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

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

更奇怪的是,直到我们达到将源行拖入数据库的某个限制,在几天之内性能刚刚下降的情况下,性能还是不错的-再多花一些源行。

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.