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

Is a view faster than a simple query?

提问人:JohnIdol 提问时间:1/13/2009 最后编辑:Peter MortensenJohnIdol 更新时间:8/13/2022 访问量:320234

问:

是一个

select *  from myView

创建视图的速度比查询本身更快(为了获得相同的 resultSet):

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

?

与简单查询相比,我并不完全清楚该视图是否使用了某种缓存,使其更快。

SQL Server 性能

评论

11赞 Muflix 2/13/2017
我不确定一个视图,但嵌套视图是整体性能地狱。

答:

824赞 10 revs, 4 users 79%Mark Brittingham #1

是的,视图可以分配聚集索引,当它们分配时,它们将存储临时结果,从而加快生成的查询速度。

Microsoft自己的文档非常清楚地表明视图可以提高性能。

首先,用户创建的大多数视图都是简单视图,不使用此功能,因此与直接查询基表没有什么不同。简单的视图是就地扩展的,因此不会直接有助于性能改进 - 这是事实。但是,索引视图可以显著提高性能。

让我直接进入文档:

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

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

同样,文档:

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

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

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

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

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

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

更新3:出现了一个问题,即索引视图是否只使用放置在基础表上的索引。也就是说,套用一句话:“索引视图只是标准索引的等价物,它没有为视图提供任何新的或独特的内容。当然,如果这是真的,那么上面的分析是不正确的!让我引用 Microsoft 文档中的一句话来说明为什么我认为这种批评是无效或不正确的:

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

结合上面关于物理存储中数据持久性的引用以及文档中关于如何在视图上创建索引的其他信息,我认为可以肯定地说,索引视图不仅仅是一个缓存的 SQL 选择,它恰好使用在主表上定义的索引。因此,我继续坚持这个答案。

评论

6赞 Mark Brittingham 1/13/2009
Ryan 的观点很好:观点不是提高性能(尽管我指出了很小的改进)。它是为了简化其他查询或标准化对数据的访问。
33赞 BradC 1/14/2009
是的,索引视图可以显著提高性能。但索引视图不仅仅是“视图”,一般来说,普通的“视图”并不比其关联的查询快。
12赞 annakata 1/14/2009
@Charles - 是否是索引并不重要,视图可以利用索引而原始查询不能这一事实就足够了
230赞 annakata 1/14/2009
/赞扬@Mark坚持自己的立场并理性地论证这一点
9赞 Charles Bretana 1/14/2009
由于一个表只能有一个 clusterdee 索引,并且您可以在视图上创建单独的聚簇索引(因为聚簇索引中的字段独立地保留在索引页中),因此这是一个作弊(work-arounnd?),它允许您在一个表上获取两个聚簇索引。
16赞 Ryan Guill 1/13/2009 #2

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

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

我会想出一个稍微复杂的例子,然后自己安排时间看看。

评论

2赞 annakata 1/13/2009
视图的另一个原因是在基于角色的模型中协助访问控制
1赞 Mark Brittingham 1/13/2009
你对性能改进的看法是错误的。在我最初的评论中,我没有解释足够的内容来说服一些人,但 MS 有关于如何使用视图来提高性能的明确文档。请参阅下面的我(现在被严重否决)的回应。
6赞 Otávio Décio 1/13/2009 #3

如果创建实例化视图(使用架构绑定),则速度可能会更快。非具体化视图的执行方式与常规查询相同。

评论

0赞 Sam Saffron 11/15/2009
架构绑定与性能关系不大,它将视图的架构绑定到基础表,使其保持同步,并且是索引视图的先决条件。
0赞 j2emanue 9/21/2020
物化视图和视图是一回事吗?我认为它们是,但具体化的视图存储在磁盘中,视图可能只是在内存中,对吧?
4赞 E.J. Brennan 1/13/2009 #4

我的理解是,不久前,视图会更快,因为 SQL Server 可以存储执行计划,然后使用它,而不是尝试动态找出一个。我认为现在的性能提升可能不像以前那么大了,但我不得不猜测使用该视图会有一些边际改进。

评论

0赞 annakata 1/13/2009
这是我的理解:过去很重要,现在不再重要了
0赞 AnonJr 1/13/2009
从性能的角度来看,它不是作为访问限制的一种手段。但那将是另一个话题。;)
0赞 annakata 1/14/2009
哦,当然,有很多很好的理由使用视图,而不是一个使用原始查询的理由:P
0赞 Nick.Mc 11/14/2022
SQL 还可以存储股票标准 sql 查询的执行计划
2赞 Tony Andrews 1/13/2009 #5

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

评论

1赞 AnthonyWJones 1/13/2009
如果视图是一小组字段,并且这些字段随后被索引覆盖,那么 SQL Server 是否足够聪明,可以在完成第二种形式的查询时使用该覆盖索引?
0赞 keithwarren7 1/13/2009 #6

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

14赞 Charles Bretana 1/13/2009 #7

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

显然,一般而言,视图的本质(有人认为它应该被频繁使用以使其成为视图)通常比任何任意 SQL 语句更有可能被“重用”。

1赞 JosephStyons 1/13/2009 #8

存储执行计划应该有一些微不足道的收益,但可以忽略不计。

0赞 CAReed 1/13/2009 #9

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

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

评论

0赞 Nick.Mc 11/14/2022
不。标准查询也会缓存其查询计划。
8赞 Jordan 1/14/2009 #10

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

评论

0赞 Mark Brittingham 1/14/2009
谢谢乔丹...很高兴听到所有这些理论在现实世界中都有效。
0赞 Muflix 2/13/2017
我有嵌套视图(View in View)的经验,但性能非常差。当所有视图都重写为子选择时,性能要快很多倍,所以也许有一个地方可以进行一些严肃的测试。
0赞 Nick.Mc 11/14/2022
听起来您没有运行相同的 SQL(“重写视图”)。还可能涉及一些缓存。
62赞 BradC 1/14/2009 #11

一般来说,不可以。视图主要用于方便和安全性,并且(本身)不会产生任何速度优势。

也就是说,SQL Server 2000 及更高版本确实具有一项称为“索引视图”的功能,该功能可以大大提高性能,但需要注意以下几点:

  1. 并非每个视图都可以制作成索引视图;它们必须遵循一组特定的准则,这(以及其他限制)意味着您不能包含常见的查询元素,如 、 、 或 。COUNTMINMAXTOP
  2. 索引视图使用数据库中的物理空间,就像表上的索引一样。

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

您可以。。。

  • 视图定义可以引用 相同的数据库。
  • 创建唯一聚簇索引后,其他非聚簇索引 可以针对视图创建索引。
  • 您可以更新基础表中的数据,包括插入、 更新、删除甚至截断。

你不能。。。

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

评论

4赞 Aaron Kempf 1/10/2013
完全不同意...从视图读取允许重写 SQL。从视图读取(比从视图的转储中读取)通常更快。
0赞 BradC 1/10/2013
@AaronKempf,我很想看到一些参考资料,这不是我的经验。当我搜索“查看重写的 SQL”时,我得到的所有结果都是指 Oracle,而不是 SQL Server,例如 docs.oracle.com/cd/E14072_01/server.112/e10810/qrbasic.htm
0赞 Aaron Kempf 1/11/2013
我昨天刚刚对它进行了一些基准测试,我惊呆了。基本上,如果我从视图(到表)中转储,我运行的任何查询都会变慢。因为大多数查询像黄油一样通过视图,并被查询优化器重写。至少我是这么认为的。我很快就会尝试写一篇关于它的博客文章,基准测试是相当吸引人的东西。基本上,视图对性能有很大帮助。
0赞 BradC 1/11/2013
@AaronKempf 不确定这是否与原始问题相同(这是关于查询与将相同的查询放入视图中)。无论如何,我看不出将视图具体化到表中会如何使其变慢(这正是索引视图的作用),除非您的新表没有良好的索引。
1赞 user2864740 12/12/2020
11 年后,鉴于“一些 [小] 警告”,我仍然没有找到很多索引视图的好候选者。:|
1赞 kta 10/7/2011 #12

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

评论

0赞 kta 10/7/2011
我们如何编写/设计查询非常重要。
1赞 MattE 5/16/2019
我发现在许多情况下,使用 CTE 来限制从表返回的数据,然后执行 CTE 之外的所有工作/联接等,这极大地提高了性能
2赞 Dasboot 3/15/2013 #13

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

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

所以这完全取决于情况。

1赞 Mohammad Reza Shahrestani 4/18/2017 #14

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

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

您甚至可以在视图上创建索引,以满足更快的搜索要求。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+

1赞 Ian 6/8/2020 #15

出乎所有人的意料,在某些情况下,观看速度要慢得多。

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

最后一个查询,提取了大约 200 行,将需要 45 分钟以上!该查询基于一连串的视图。也许有 3-4 级深。

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

我们甚至发现,我们甚至可以将每个视图写入一个临时表中,并用它来代替视图进行查询,这仍然比简单地使用嵌套视图要快得多。

更奇怪的是,性能一直很好,直到我们达到被拉入数据库的源行的某个限制,性能在几天的时间里就断崖式下降了——只需要再增加几个源行。

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

-2赞 JohnH 6/8/2020 #16

我遇到了这个线程,只是想分享 Brent Ozar 的这篇文章,作为使用可用性组时要考虑的事情。

Brent Ozar 错误报告

0赞 Muhammad Bilal 8/13/2022 #17

不。视图只是实际长 SQL 查询的缩写形式。但是,是的,您可以说实际查询比查看命令/查询更快。

第一个视图查询将转换为简单查询,然后执行,因此视图查询的执行时间比简单查询长。

当您使用联接 b/w 多个表时,可以使用 sql 视图,以简单的方式一次又一次地重用复杂的查询。