使用 SQL Server 2000 索引视图提高性能

  提供一种机制,允许开发人员定制用户如何才能以逻辑方式查看存储在基表中的数据。

  视图上创建唯一的群集索引和非群集索引,可以改进最复杂查询的数据访问性能。在 SQL

  从数据库管理系统 (DBMS) 的观点来看,视图是数据(元数据)的说明。创建典型视图时

  ,通过 SELECT 语句(定义一个显示为虚拟表的结果集)来定义元数据。当其它查询的 FROM

  子句中引用了某个视图时,将从系统目录中检索该元数据,并对其进行扩展以代替该视图的引

  如果是非索引视图,视图在运行时将被实体化。任何计算(如联接或聚合)都在为每个引

  用该视图的查询执行查询期间进行。(视图并不总需要被完全实体化。查询可以包含其它一些

  谓词、联接或聚合,以应用于该视图所引用的表和视图。)在视图上创建了唯一的群集索引之

  后,视图的结果集会立即被实体化并持续保存在数据库的物理存储空间中,以便节省这种操作

  在执行查询时,有两种方法可以使用索引视图。查询可直接引用索引视图,更重要的是,

  如果查询优化器确定视图能够替换为查询的部分或全部,而且这是低成本的查询计划,则可以

  选择索引视图。第二种情况是使用索引视图代替基础表及其普通索引。此时,不需要在查询中

  引用视图,查询优化器即可在执行查询期间使用该视图。这样,现有的应用程序无需更改即可

  使用索引来提高查询性能并不是什么新观念,不过,索引视图还具有使用标准索引不能获

  能够预先计算聚合并将其存储在索引中,从而最大限度地减少在执行查询期间进行成本很

  下图说明了查询优化器使用索引视图时一般能够提高多少性能。提供的查询复杂程度各不

  相同(例如,聚合计算的数量、所用表的数量或谓词数),并包括来自实际生产环境的数百万

  视图的辅助性非群集索引可以提高其它查询性能。与表的辅助索引类似,视图的辅助索引

  也可以提供更多选项,以便查询优化器在编译过程中从中进行选择。例如,如果查询包括群集

  索引未涉及的列,优化器可以在计划中选择一个或多个辅助索引,从而避免对索引视图或基表

  由于索引需要不断维护,所以为架构添加索引会增加数据库的额外开销。因此应该认真考

  实现索引视图之前,请先分析数据库的工作量。运用自己对查询以及各种工具(例如

  SQL 分析器)的知识来鉴别使用索引视图可以获益的查询。如果经常进行聚合和联接,最好使

  并非所有查询都会从索引视图中获益。与普通索引类似,如果未使用索引视图,就没有好

  处可言。在此情况下,不但不能提高性能,还会加大磁盘空间的占用、增加维护和优化的成本

  。但是,如果使用了索引视图,它们可以(成数量级地)明显地提高数据访问的性能。这是因

  为查询优化器使用存储在索引视图中的预先计算的结果,从而大大降低了执行查询的成本。

  查询优化器只在查询的成本比较大时才考虑使用索引视图。这样可以避免在查询优化成本

  超出因使用索引视图而节省的成本时,试图使用各种索引视图。当查询成本低于 1 时,几乎

  相反,包含许多写入的联机事务处理 (OLTP) 系统或更新频繁的数据库,可能会因为要同

  SQL Server 查询优化器可自动确定何时可以将索引视图用于给定的查询执行中。查询中

  无需直接引用视图,优化器就可以将该视图用于查询执行计划。因此,无需对现有的应用程序

  本身进行任何更改,这些应用程序即可利用索引视图。唯一需要做的就是创建索引视图。

  查询优化器会考虑几个条件来确定索引视图能涵盖部分查询还是整个查询。这些条件符合

  查询选择列表中的所有表达式都必须源自于视图选择列表或源自于不包括在视图定义中的

  查询搜索条件谓词必须是视图定义中搜索条件谓词的超集。视图搜索谓词中的每个合取项

  查询搜索条件谓词中的所有列(属于视图定义中的表)都必须出现在下列一项或多项中:

  如果查询包含多个 FROM 子句(子查询、派生表、UNION),优化器可以选择多个索引视

  注意: 也存在例外情形,即优化器可能将两个 FROM 子句折叠成一个(将子查询折叠

  成联接或将派生表折叠成联接变体)。如果出现此类情况,索引视图替换可能会涵盖原查询中

  本文档结尾介绍了演示这些条件的查询示例。而建议的最佳方法就是:让查询优化器来确

  NOEXPAND 选项强制查询优化器象对待包含群集索引的普通表一样对待视图。在此情况下

  另外,用户可以在查询结束时通过使用 EXPAND VIEWS 选项,明确地将索引视图排除在考

  如果使用该选项,查询优化器在评估低成本的方法(该方法涉及查询中引用的列)时将忽

  为数据库系统找到适当的索引集是相当复杂的。尽管在设计普通索引时要考虑许多可能性

  ,但将索引视图添加到架构会极大地增加设计和潜在结果的复杂性。例如,索引视图可用于:

  应同时设计表的索引和索引视图,以便从各个结构中获得最佳结果。由于索引和索引视图

  都可能对给定的查询有用,所以单独设计它们会导致多余的建议方案,以致存储和维护开销较

  高。在调整数据库的物理设计时,必须均衡考虑各种查询集的性能要求与数据库系统必须支持

  的更新操作。因此,为索引视图找到一种合理的物理设计是一项很具挑战性的任务,因而应该

  如果存在许多索引视图可供查询优化器考虑用于特定查询,查询优化成本会显著增加。查

  询优化器可能考虑为查询中表的任意子集定义的所有索引视图。拒绝每一个视图之前,必须对

  它进行语法分析,然后研究其是否可能成为潜在的替换体。这可能需要一些时间,尤其是在有

  视图必须符合几项要求,您才能为其创建唯一的群集索引。在设计阶段,请考虑以下要求

  创建基表、视图和索引以及修改基表和视图中的数据时,必须正确设置某些 SET 选项(

  在本文档的后文中讨论)。另外,如果这些 SET 选项正确,查询优化器将不考虑索引视图。

  例如,包含某列的 SUM 和某列的 COUNT_BIG 的索引视图可用于包含函数 SUM、COUNT、

  COUNT_BIG 或 AVG 的查询。由于只需检索视图中的少数几行,而不是基表中的所有行,且执

  通过使用最少的列数和尽可能少的字节数,优化器在查找行数据时可获得最高的效率。相

  反,如果定义了大的群集索引关键字,则为视图定义的任何辅助性非群集索引都将明显增大,

  在单纯的聚合情况下,如果索引视图的大小类似于原表的大小,使用索引视图可能无法明

  有时可能无法设计出能满足整个查询需要的索引视图。此时即可考虑创建这样一些索引视

  经常执行的查询会聚合一个数据库中的数据,再聚合另一个数据库中的数据,然后联接结

  果。由于索引视图不能引用多个数据库中的表,所以您不能设计一个视图来执行整个进程。不

  过,可以为要进行聚合的每个数据库创建索引视图。如果优化器能够将索引视图与现有查询相

  匹配,至少聚合处理将会因为不必记录现有查询而提高速度。尽管联接处理不会加快,整个查

  经常执行的查询会聚合多个表中的数据,然后使用 UNION 来将结果结合起来。UNION 不

  允许在索引视图中使用。您可以设计一些视图来执行每个单独的聚合运算。然后优化器可以选

  择索引视图来加快查询的速度,而无需记录查询。尽管 UNION 处理没有改进,单个聚合进程

  “索引微调向导”除建议使用基表的索引之外,还建议使用索引视图。使用该向导可提高

  管理员确定索引和索引视图相结合的能力,从而优化针对数据库执行的典型混合查询的性能。

  由于“索引微调向导”强制使用所有必需的 SET 选项(以确保结果集的正确性),其索

  引视图将会成功创建。不过,如果您的应用程序的选项没有按照要求设置,可能无法利用这些

  SQL Server 自动维护索引视图,这与维护任何其它索引的情况类似。对于普通索引而言

  ,每个索引都直接连接到单个表。通过对基础表执行每个 INSERT、UPDATE 或 DELETE 操作,

  索引视图的维护与此类似。不过,如果视图引用了多个表,则对这些表中的任何一个进行

  更新都需要更新索引视图。与普通索引不同的是,对任何一个参与的表执行一次行插入操作都

  可能导致在索引视图中进行多次行插入操作。更新和删除操作的情况也是如此。因此,较之于

  在 SQL Server 2000 中,某些视图可以更新。如果某个视图可以更新,则使用 INSERT

  、UPDATE 和 DELETE 语句可通过该视图直接修改根本基表。为某个视图创建索引并不会妨碍

  数据库中需要有一个额外的存储空间用于索引视图。索引视图的结果集以类似于典型表存

  SQL Server 自动维护视图。因此,对定义视图所据的基表的任何更改都可能引起视图索

  一个视图获得的净性能提高就是视图提供的查询执行节约总计与存储和维护该视图耗费的

  估计视图将占用的所需存储空间要相对简单一些。用 SQL 查询分析器的“显示估计的执

  行计划”工具求视图定义中 SELECT 语句的值。该工具将得出查询返回的行数和行大小的近似

  值。将这两个值相乘,即可估计出视图的可能大小。不过这只是一个近似值。视图索引的实际

  从 SQL Server 执行的自动维护考虑因素的观点出发,“显示估计的执行计划”的功能可

  能会对此开销的影响有所了解。如果用 SQL 查询分析器评估修改视图的语句(针对视图的

  UPDATE 语句、针对基表的 INSERT 语句),SHOWPLAN 将包括该语句的维护操作。同时考虑

  通常建议对视图或基表进行的任何修改和更新都应该尽可能地成批执行,而不要单独进行

  如果在执行查询时启用不同的 SET 选项,则在 SQL Server 中对同一个表达式求值会产

  式得出的结果却是 abc。索引视图要求多个 SET 选项的值都固定,以确保这些视图能够得

  只要出现以下情况,就必须将下表中的 SET 选项设置为要求的值列中所示的值:

  索引视图的定义必须是确定性的。如果选择列表中的所有表达式以及 WHERE 和 GROUP

  BY 子句都是确定性的,则视图就是确定性的。只要用特定的一组输入值对确定性表达式进行

  求值,一定会返回同一个结果。只有确定性函数可以加入确定性表达式。例如,DATEADD 是确

  定性函数,因为将任何给定的一组变量值赋予它的三个参数进行求值,返回的总是同一个结果

  。而 GETDATE 则不是确定性函数,因为始终用同一个变量调用它,而它每次执行后返回的值

  即便某个表达式是确定性的,但如果其中包含浮动表达式,确切的结果就可能取决于处理

  器的体系结构或微代码的版本。要确保 SQL Server 2000 中数据的完整性,此类表达式只能

  加入索引视图的非关键列。不包含浮动表达式的确定性表达式被称为精确的表达式。只有精确

  的确定性表达式可以加入索引视图的关键列和 WHERE 或 GROUP BY 子句。

  效的输入(列不是确定性的),则返回 NULL。例如,SELECT COLUMN

  注意: 该 SELECT 语句所基于的视图能够在示例部分找到(视图 1)。

  除“设计准则”、“使用 SET 选项以获得一致的结果”和“使用确定性函数”部分中列

  基表在创建时必须正确设置 SET 选项,否则就不能被包含架构绑定的视图引用。

  注意: 索引视图可以包含浮动列,不过,此类列不能包含在群集索引关键字中。

  这些限制只适用于索引视图定义。查询可以在其执行计划中使用索引视图,即便该索引视

  如果视图定义中包含 GROUP BY 子句,唯一群集索引的关键字只能引用 GROUP BY 子句中

  本部分的示例阐述索引视图在两种主要查询(聚合和联接)中的使用问题。同时还说明查

  询优化器在确定某个索引视图是否可用时使用的条件。有关这些条件的完整列表,请参阅查询

  式执行。创建视图的前后,最好使用 SQL 查询优化器中的“显示执行计划”工具来查看查询

  优化器选定的计划。尽管示例中阐述了优化器是如何选择成本最低的执行计划的,但因为

  以下查询显示如何从 Order Details 表中返回具有最大总折扣的五种产品的两个方法。

  哈希匹配/聚合运算符,该运算符基于 GROUP BY 列将选定的行放入哈希表,然后计算每

  添加包括 Rebate 列所需聚合的索引视图将更改查询 1 的查询执行计划。在数百万行的

  第一个查询的执行计划显示 Vdiscount1 视图由查询优化器使用。不过,由于该视图不包

  查询优化器选择该视图是因为它提供了最低的执行成本,尽管在查询中并未引用该视图。

  查询 3 类似于前几个查询,只是 ProductID 已被 OrderID 所取代,视图定义中没有包

  括该列。这违背了以下条件:查询选择列表中的所有表达式都必须能从未包括在视图定义内的

  要求单独的索引视图来满足该查询。可以对 Vdiscount2 进行修改,使它包括 OrderID,

  但是所生成视图的行数将与原表的行数相同,因此,提供的性能也不会高于使用基表所提供的

  索引视图的定义中不能包括复杂的聚合(例如,STDEV、VARIANCE、AVG),不过,如果

  索引视图中包括几个联合起来执行复杂聚合的简单聚合函数,即可用于执行包含 AVG 的查询

  该索引视图包含执行 AVG 函数所需的简单聚合函数。在创建了视图 3 后执行查询 4 时

  ,执行计划会显示正被使用的视图。优化器可以从视图的简单聚合列 Price 和 Count 中导出

  该查询与查询 4 相同,只不过包括一个附加搜索条件。即使该附加搜索条件只引用未包

  查询优化器不能将视图 3 用于该查询。附加搜索条件 od.UnitPrice10 包含视图定义内的表中的列,而该列却不出现在 GROUP BY 列表中,搜索谓词也不出现在视图定义中。

  相反,查询优化器可以将视图 3 用于查询 7,原因是新搜索条件 od.ProductID in

  该视图在视图定义中包括了列 od.Discount,可以满足查询 6 的条件。

  视图 4 的同一个索引还将用于一个添加了与表 Orders 的联接的查询。该查询符合以下

  条件:查询 FROM 子句中列出的表是索引视图的 FROM 子句中表的超集。

  最后两个查询是查询 8 的变体。每个变体都违背了一个优化器条件,因此与查询 8 不

  由于视图定义中的 UnitPrice 10 与查询中的 UnitPrice 25 之间的 WHERE 子句不匹配,所以 Q8a 不能使用索引视图。查询搜索条件谓词必须是视图定义中搜索条件谓词的超集。

  注意,表 Orders 没有参与索引视图 V4 的定义。尽管如此,在该表中添加谓词将禁止使

  用索引视图,原因是添加的谓词可能会消除聚合中的其它行(如查询 8b 中所示)。

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。