博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
四、物理优化(2)索引视图
阅读量:5736 次
发布时间:2019-06-18

本文共 4009 字,大约阅读时间需要 13 分钟。

一、视图的概念

1. 虚拟表

  SQL Server中的视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。 

 

2. 使用视图的原因

  视图是存储在数据库中的查询的SQL 语句,它主要出于两种原因:

(1)简化Select 查询

  通过视图,不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。

 

(2)安全原因

  视图可以隐藏一些数据,如:薪资表,可以用视图只显示雇员编号、姓名等基础信息,而不显示身份证号码、薪资数等敏感信息。

  SQL Server 2005 及后续版本,将系统表隐藏起来,只提供一些系统视图用于查看系统表的部分数据。

 

3. 对视图的操作

  从数据库系统内部来看,视图是由一张或多张表中的数据组成的,从数据库系统外部来看,视图就如同一张表一样,对表能够进行的一般操作都可以应用于视图,例如查询、插入、修改、删除操作等。

  对于标准视图而言,结果集不永久存储在数据库中。每次查询引用标准视图时,SQL Server 都会在内部将视图的定义替换为该查询,直到修改后的查询仅引用基表。然后,它将照常运行所得到的查询。生成视图结果的过程称为视图具体化。

  不能对视图创建筛选索引。但是,查询优化器可以从对视图中引用的表定义的筛选索引中获益。对于从视图中选择数据的查询,如果查询结果正确,查询优化器会考虑对此查询使用筛选索引。

 

二、视图的分类

1. 系统视图

  为了防止用户修改SQL Server系统中的一些重要的表,系统提供了一些只读的系统视图。这些视图一般属于sys架构。

 

2. 用户定义的视图 

  用户定义的视图是通过T-SQL语句或者GUI创建的。

 

三、索引视图

1. 概念

  SQL Server 2000 及后续版本支持在视图上定义索引。

   对于涉及对大量的行进行复杂处理的非索引视图,为引用视图的每个查询动态生成结果集的开销会很大。这类视图包括聚集大量数据或联接许多行的视图。若经常在查询中引用这类视图,可通过在视图上创建唯一聚集索引来提高性能。在视图上创建唯一聚集索引时将执行该视图,并且结果集将存储在数据库中,就像带有聚集索引的表一样。

 

2. 索引视图的好处

(1)加速查询

  对于涉及对大量的行进行复杂处理的视图,由于结果集已经保存为一张带有聚集索引的表,因此无需重新计算,索引视图有明显的速度优势。

 

(2)查询优化器引用

  即使未在 FROM 子句中指定使用视图,查询优化器也可以使用索引视图。这样一来,可从索引视图检索数据而无需重新编码,设计良好的索引视图可以加快许多查询的处理速度。例如:

CREATE VIEW ExampleView WITH SCHEMABINDING
AS
SELECT GroupKey, SUM(Colx) AS SumColx, COUNT_BIG(Colx) AS CountColx
FROM MyTable
GROUP BY GroupKey

  此视图不仅能满足直接引用视图ExampleView 时的查询,还可用于满足查询基表MyTable并包含 SUM(Colx)、COUNT_BIG(Colx)、COUNT(Colx) 和 AVG(Colx) 等表达式的查询。因为所有这些查询只须在视图中检索少量的行,而不需要从基表中读取全部行,所以查询速度将更快。

  同样,聚合数据并按天分组的索引视图可用于满足聚合 1 天以上(如 7、30 或 90 天)的几个不同范围的查询。

 

3. 索引视图的限制

(1)版本限制

  索引视图可以在 SQL Server 2008 的任何版本中创建。

  在 SQL Server 2008 Enterprise 中,查询优化器会自动考虑索引视图。若要在其他所有版本中使用索引视图,则必须使用 NOEXPAND 表提示。

 

(2)索引的唯一性

  视图的聚集索引必须唯一,从而提高了 SQL Server 在索引中查找受任何数据更改影响的行的效率。

  必须设置特定的 SET 选项后才能在视图上创建索引。

 

(3)维护开销

  与基表上的索引相比,对索引视图的维护可能更复杂。

 

 

四、创建索引视图

1. 基本方法

  在视图上创建聚集索引可存储创建索引时生成的结果集。索引视图还自动反映自创建索引后对基表数据所做的更改,这一点与在基表上创建的索引相同。当对基表中的数据进行更改时,索引视图中存储的数据也反映数据更改。

  视图上的索引命名规则与表上的索引命名规则相同。唯一区别是表名由视图名替换。

  尽管 CREATE UNIQUE CLUSTERED INDEX 语句仅指定组成聚集索引键的列,但视图的完整结果集将存储在数据库中。

  在视图上创建的第一个索引必须是唯一聚集索引。在创建唯一聚集索引后,可创建其它非聚集索引。若除去视图,视图上的所有索引也将被除去。若除去聚集索引,视图上的所有非聚集索引也将被除去。可分别除去非聚集索引。除去视图上的聚集索引将删除存储的结果集,并且优化器将重新像处理标准视图那样处理视图。

 

2. 对视图的要求

  在对视图创建聚集索引之前,该视图必须符合下列要求:

(1)当执行 CREATE VIEW 语句时,ANSI_NULLS 和 QUOTED_IDENTIFIER 选项必须设置为 ON。OBJECTPROPERTY 函数通过 ExecIsAnsiNullsOn 或 ExecIsQuotedIdentOn 属性为视图报告此信息。

(2)要执行所有 CREATE TABLE 语句以创建视图引用的表,ANSI_NULLS 选项必须设置为 ON。

(3)视图不能引用任何其他视图,只能引用基表。而且所有基表必须与视图位于同一数据库中,并且所有者也与视图相同。

(4)必须使用 SCHEMABINDING 选项创建视图。架构绑定将视图绑定到基础基表的架构。必须已使用 SCHEMABINDING 选项创建了视图引用的用户定义函数。

(5)表和用户定义函数必须由视图中由两部分组成的名称引用。不允许由一部分、三部分和四部分组成的名称引用它们。

(6)视图中的表达式引用的所有函数必须是确定的。非确定性函数,例如GETDATE、NEWID、@@total_errors等。还有一些函数在以确定性方式指定后,才可用于索引视图,例如CAST、CONVERT、RAND等。

 

3. CREATE INDEX语句的要求

  CREATE INDEX 除了符合 CREATE INDEX 的常规要求之外,还必须符合下列要求:

执行 CREATE INDEX 语句的用户必须是视图所有者。
执行 CREATE INDEX 语句时,下列 SET 选项必须设置为 ON:ANSI_NULLS、ANSI_PADDING、ANSI_WARNINGS、CONCAT_NULL_YIELDS_NULL、QUOTED_IDENTIFIER
NUMERIC_ROUNDABORT 选项必须设置为 OFF。这是默认设置。
如果数据库在 80 或更低的兼容模式下运行,则 ARITHABORT 选项必须设置为 ON。
创建聚集索引或非聚集索引时,IGNORE_DUP_KEY 选项必须设置为 OFF(默认设置)。
即使 CREATE INDEX 语句中未引用 text、ntext 或 image 列,视图中也不能包含这些列。
如果视图定义中的 SELECT 语句指定了一个 GROUP BY 子句,则唯一聚集索引的键只能引用在 GROUP BY 子句中指定的列。
构成索引键列值的不精确表达式必须引用视图下基表中的存储列。该列可以是常规存储列,也可以是持久化计算列。其他不精确表达式不能作为索引视图的键列的一部分。

 

 

五、索引视图的应用场景 

1. 权衡

  对索引视图的维护将增加系统开销,因此需要权衡以下两者:

(1)查询视图结果所需的开销。如果是频繁查询,请考虑累计的开销。

(2)维护索引视图所需的开销。

 

2. 建议

  建议以下场景:

(1)需要频繁查询的视图,同时基表不具有大量更新。

(2)视图映射在相对静态的数据上。

(3)处理大量行或经常查询的、带有联接和聚合操作的视图。 

(4)需要复杂计算的视图。

 

3. 索引视图与查询相结合

  虽然对可索引的视图类型的限制可能使您无法设计完全解决某个问题的视图,但仍可以设计多个较小的索引视图,从一定程度上加快进程的速度。请考虑下列示例:

  假设有一个经常执行的查询首先要聚合一个数据库中的数据,然后聚合另一个数据库中的数据,再将结果联接起来。因为索引视图不能引用多个数据库中的表,所以不能设计单个视图来完成整个处理过程。但是,您可以在每个数据库中创建一个索引视图,分别为每个数据库执行聚合操作。如果优化器可以将这些索引视图与现有查询匹配,那么至少会加快聚合处理的速度,因为无须对现有查询重新编码。虽然联接处理速度没有加快,但因为查询使用了索引视图中存储的聚合,所以总体速度将加快。

  假设有一个经常执行的查询首先要聚合几个表中的数据,然后使用 UNION 组合结果。索引视图中不允许使用 UNION。同样,您可以设计一些视图来执行每个聚合操作。这样一来,优化器就可以选择索引视图以加快查询的速度,而无须对查询重新编码。尽管 UNION 处理速度没有提高,但每个聚合进程的速度确实提高了。 

 

 

本文结语:

  维护索引视图需要开销,但可以提高查询效率。企业版的查询优化器会自动使用索引视图。

 

转载地址:http://lvrwx.baihongyu.com/

你可能感兴趣的文章
PHP 命令行模式实战之cli+mysql 模拟队列批量发送邮件(在Linux环境下PHP 异步执行脚本发送事件通知消息实际案例)...
查看>>
PS 如何使用液化工具给人物减肥
查看>>
cvc-complex-type.2.4.c: The matching wildcard...
查看>>
android 读取json数据(遍历JSONObject和JSONArray)
查看>>
pyjamas build AJAX apps in Python (like Google did for Java)
查看>>
<JavaScript语言精粹>-读书笔记(一)
查看>>
NPM教程
查看>>
Java学习笔记(40)——Java集合12之fail-fast
查看>>
Centos 配置IP的方式
查看>>
Go 的吉祥物,萌不萌
查看>>
Java 的swing.GroupLayout布局管理器的使用方法和实例
查看>>
Android中Activity和Fragment的生命周期的对比
查看>>
C++Primer_笔记_异常处理
查看>>
分区交换 alter table exchange partition 在线表 历史表交换
查看>>
zabbix详解:(二)添加被监控机器
查看>>
设计模式单列
查看>>
人像模式的灯光效果?iPhone 8开挂袭来
查看>>
Linux下MongoDB安装与配置
查看>>
DSL配置(PPPOA)
查看>>
WEBRTC执行流程
查看>>