由于在用户引用视图的时候,每次都需要从数据库中重新查询数据,即使基表中的数据没有变化也是如此。可是,每当用户引用视图时查询动态生成结果集会产生比较大的系统开销,特别是对于那些涉及大量进行复杂处理的视图。如有时,用户需要统计一年的销售表表,需要对每月的销售金额、每个业务员接单的金额、每个产品涉及到的金额等等进行统计,这个查询就会消耗系统比较多的资源。如果每次查询这个统计视图的话,数据库都从基表中查询并生成相应的结果集,会大大影响视图的性能。
为了解决这个问题,数据库专家提出了索引视图的概念。即通过对视图创建唯一聚集索引来提高数据库性能。对视图创建唯一索引后,结果集就会被存储在数据库表中,就好戏那个带有聚集索引的表一样。如此的话,不用每次引用视图,数据库都做一次查询作业了。而可以直接从数据库中取得这个结果集。那么就可以提高视图的执行性能了。
一、 在什么时候使用索引视图?
当然,并不是说在任何情况下为视图建立唯一聚集索引都可以提高视图的性能。俗话说,过之而不及,如果采取这种极端方式的话,往往会取得相反的结果。通常情况下,若遇到如下几种情况,则在索引视图中创建索引能够带来比较大的收益。
一是视图需要处理大量行的连接与聚合。如在进销存系统中,有一张销售订单出货情况统计表。在这张报表中,需要涉及到大量的表与行。如需要涉及到订单头表(获取订单信息)、订单行表(获取订单内容以及预计交货日期等信息)、客户信息表、运费信息表、出货单头表、出货单身表、发票信息表等表,。并且需要对表中的数据行进行重新连接。并且,还要实现部分的统计功能,如需要统计每个月的出货总额、开票总额等等;也可能需要根据客户来统计等等。这些统计工作会产生大量的聚合操作。为此,如果执行这个查询的话,当数据量一多,其运行的时间就会比较长。如果采用不带唯一聚集索引的视图的话,则每次生成这个报表都会花费比较长的时间。但是,如果对于这张表采用索引视图的话,那么其执行速度就会快的多。因为引用这张视图的时候,不用在数据库中重新查询。
二是在一些数据更新不怎么频繁的数据库应用中,如决策分析系统。决策分析系统有两个很明显的特点,一是在他的数据库系统中存储的数据不是经常需要更新、汇总的聚合数据。二是在查询时需要对大量的行进行连接、聚合操作。而且这些行所涉及到的表往往是具有大量的列或者列很大的宽表。用这些列的窄子集的查询可以从只包含查询中的列或这些列的窄超集的索引视图中获益。创建包含单个表的列的子集的窄索引视图称为“垂直分区”策略,因为它垂直拆分表。不过,这里需要注意一点。如果要垂直拆分整个表,而不是表的一个子集,建议您使用表的非聚集索引,该索引使用 INCLUDE 子句只包含所需的列,而不是索引视图。这两个方面具体的差异,笔者会在日后的文章中谈到。
所以说,并不是在任何情况下都推荐使用索引视图。如只是对于两张基表的视图,而且这些表中的数据量并不是很多,那么采取索引视图反而会降低数据库的整体性能。故是否要创建索引视图,其一般的判断标准就是两个,即是否需要对大量表中大量的行进行连接与聚合操作;另外一个就是数据库表中数据的更新程度。
二、 使用索引视图有什么限制?
在上面笔者谈到了在什么情况下适合采用索引视图。在接下去的内容中,笔者还将谈谈索引视图的限制条件。即在什么情况下,若采用索引视图则可能是事倍功半。
一是如果视图所对应的基表涉及到频繁的更新操作时,则不宜采用索引视图。因为维护索引视图的成本可能高于维护表索引的成本。如果经常更新基础数据,则维护索引视图数据的成本可能超过使用索引视图所带来的性能收益。例如,在某些决策支持分析系统中,需要对基础数据以批处理的形式定期更新,但是在更新之后主要作为只读数据进行处理。此时,数据库管理员就需要在更新数据前先把所有相关的索引视图设置为无效或者删除,然后再激活或者重新生成。这样做可以避免因数据更新而给数据库带来的额外负担,提高更新的性能;同时也利于后续的查询分析操作。