通过 SQL Server 索引视图提高性能.docx

上传人:b****8 文档编号:23676187 上传时间:2023-05-19 格式:DOCX 页数:32 大小:37.70KB
下载 相关 举报
通过 SQL Server 索引视图提高性能.docx_第1页
第1页 / 共32页
通过 SQL Server 索引视图提高性能.docx_第2页
第2页 / 共32页
通过 SQL Server 索引视图提高性能.docx_第3页
第3页 / 共32页
通过 SQL Server 索引视图提高性能.docx_第4页
第4页 / 共32页
通过 SQL Server 索引视图提高性能.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

通过 SQL Server 索引视图提高性能.docx

《通过 SQL Server 索引视图提高性能.docx》由会员分享,可在线阅读,更多相关《通过 SQL Server 索引视图提高性能.docx(32页珍藏版)》请在冰豆网上搜索。

通过 SQL Server 索引视图提高性能.docx

通过SQLServer索引视图提高性能

通过SQLServer2005索引视图提高性能

通过SQLServer2005索引视图提高性能

发布日期:

2005年04月18日

撰稿人:

EricHanson

投稿人:

GailErickson、LuborKollar、JasonWard

摘要:

本文档介绍了SQLServer2005EnterpriseEdition中经过改进的索引视图功能。

文中对索引视图进行了说明介绍,并讨论了可通过该功能改善性能的一些具体情况。

本页内容

什么是索引视图?

应用索引视图的优点

SQLServer2005的索引视图有哪些新增功能?

设计注意事项

创建索引视图

示例

有关索引视图的常见问题

如需获得更多信息

什么是索引视图?

多年以来,Microsoft®SQLServer™一直支持创建称为视图的虚拟表。

通常,这些视图的主要作用是:

提供一种安全机制,将用户限制到一个或多个基表的某个数据子集中。

提供一种机制,允许开发人员自定义用户通过逻辑方式查看存储在基表中的数据的方式。

通过SQLServer2000,SQLServer视图的功能得到了扩展,实现了系统性能方面的收益。

可在视图上创建唯一的聚集索引及非聚集索引,来提高最复杂的查询的数据访问性能。

在SQLServer2000和2005中,具有唯一的聚集索引的视图即为索引视图。

本文所讨论的内容适用于SQLServer2005,其中有许多内容也适用于SQLServer2000。

从数据库管理系统(DBMS)的角度看来,视图是对数据(一种元数据类型)的一种描述。

当创建了一个典型视图时,通过封装一个SELECT语句(定义一个结果集来表示为虚拟表)来定义元数据。

当在另一个查询的FROM子句中引用视图时,将从系统目录检索该元数据,并替代该视图的引用扩展元数据。

视图扩展之后,SQLServer查询优化器会为执行查询编译一个执行计划。

查询优化器会搜索针对某个查询的一组可能的执行计划,并根据对执行每个查询计划所需的实际时间的估计,选择所能找到的成本最低的计划。

对于非索引视图,解析查询所必需的视图部分会在运行时被具体化。

任何计算(比如:

联接或聚合)都在每个引用视图的查询执行时完成1。

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

在查询执行中,可通过两种方式使用索引视图。

查询可直接引用索引视图,或者更重要的是,如果查询优化器确定该视图可替换成本最低的查询计划中的部分或全部查询,那么就可以选定它。

在第二种情况中,使用索引视图替代基础表及其一般索引。

不必在查询中引用视图以使查询优化器在查询执行时使用该视图。

这使得现有的应用程序可以从新创建的索引视图中受益,而不必进行更改。

注意索引视图是SQLServer2000和2005各版本的一个功能。

在SQLServer2000和2005的Developer和Enterprise版本中,查询处理器可使用索引视图来解析结构上与该视图相匹配的查询,即便不按名称来引用视图。

在其他版本中,必须按名称来引用视图,并对视图引用使用NOEXPAND提示来查询索引视图的内容。

通过索引视图改善性能

运用索引提高查询性能不算是一个新概念;但是,索引视图提供了一些借助标准索引无法取得的性能收益。

索引视图可通过以下方式提高查询性能:

可预先计算聚合并将其保存在索引中,从而在查询执行时,最小化高成本的计算。

可预先联接各个表并保存最终获得的数据集。

可保存联接或聚合的组合。

该图说明了当查询优化器使用索引视图时,通常所能取得的性能改进。

所列举的查询在复杂性上有所不同(比如:

聚合计算的数量、所用表的数量或谓词的数量)并包含来自真实的生产环境的具有数百万行的表。

在视图上使用非聚集索引

其次,视图上的非聚集索引可提供更好的查询性能。

与表上的非聚集索引类似,视图上的非聚集索引可提供更多选项,供查询优化器在编译过程中选择。

例如,如果查询包含聚集索引所未涉及的列,那么优化器可在计划中选择一个或多个辅助索引,避免对索引视图或基表进行费时的完全扫描。

对架构添加索引会增加数据库的开销,因为索引需要持续的维护。

在索引数量和维护开销间寻求适当的平衡点时,应谨慎权衡。

返回页首

应用索引视图的优点

在实施索引视图前,分析数据库工作负荷。

运用查询及各种相关工具(比如:

SQLProfiler)方面的知识来确定可从索引视图获益的查询。

频繁发生聚合和联接的情况最适合使用索引视图。

无论是否频繁发生,只要某个查询需要很长的响应时间,同时快速获得响应的开销很高,那么就适合使用索引视图。

例如,一些开发人员发现为高级主管们在月末运行的报告,创建预先计算和存储查询的应答的索引视图很有用。

不是所有的查询都能从索引视图中获益。

与一般索引类似,如果未使用索引视图,就无法从中受益。

在这种情况下,不仅无法实现性能改善,而且会在磁盘空间、维护和优化方面产生额外的成本。

然而,当使用索引视图时,可大大改善(在数量级上)数据访问。

这是因为查询优化器使用存储在索引视图(大幅降低了查询执行的成本)中预先计算的结果。

查询优化器仅考虑对具有高成本的查询使用索引视图。

从而避免出现这样的情况:

在查询优化成本高于使用索引视图所节约的成本时尝试匹配各种索引视图。

在成本少于1的查询中很好使用索引视图。

从实施索引视图中获益的应用程序包括:

决策支持工作负荷

数据集市

数据仓库

联机分析处理(OLAP)存储和源

数据挖掘工作负荷

从查询类型和模式方面来看,获益的应用程序一般包含:

大型表的联接和聚合

查询的重复模式

几组相同或重叠的列上的重复聚合

相同键上相同表的重复联接

以上各项的组合

相反,执行许多写入操作的联机事务处理(OLTP)系统或者频繁更新的数据库应用程序可能无法运用索引视图,因为同时更新视图和底层基表会带来更高的维护成本。

查询优化器如何使用索引视图

SQLServer查询优化器自动决定何时对给定的查询执行使用索引视图。

不必在查询中直接引用视图以供优化器在查询执行计划中使用。

所以,现有的应用程序可运用索引视图,而不用更改应用程序本身;只是必须创建索引视图。

优化器考虑事项

查询优化器通过考虑几个条件来决定索引视图能否涵盖整个或部分查询。

这些条件对应查询中的一个FROM子句并由下列这几个部分组成:

查询FROM子句中的表必须是索引视图FROM子句中的表的超集。

查询中的联接条件必须是视图中的联接条件的超集。

查询中的聚合列必须可从视图中的聚合列的子集派生。

查询选择列表中的所有表达式必须可从视图选择列表或未包含在视图定义中的表派生。

如果与其他谓词所匹配的行的超集相匹配,那么该谓词将归入另一个谓词。

例如,“T.a=10”归入“T.a=10andT.b=20”。

任何谓词都可归入其自身。

视图中限制表值的那部分谓词必须归入查询中限制相同表的那部分谓词。

此外,必须以SQLServer可验证的方式实现这一点。

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

1.

一个GROUPBY列表。

2.

视图选择列表(如不存在GROUPBY)。

3.

视图定义中相同或等价的谓词。

情况

(1)和

(2)允许SQLServer对视图的列应用查询谓词,以便进一步限制视图的列。

情况(3)比较特殊。

在这种情况下,不需要对列进行筛选,因此该列不必出现在视图中。

如果查询不止包含一个FROM子句(子查询、派生表、UNION),优化器可能选择几个索引视图来处理查询,并将它们应用到不同FROM子句。

2

本文档的末尾提供了涉及这些情况的具体查询。

推荐的最佳实务是让查询优化器决定在查询执行计划中使用哪些索引(如果有的话)。

使用NOEXPAND视图提示

当SQLServer处理按名称引用视图的查询时,视图的定义只有在仅引用基表时才会被正常扩展。

这个过程称为视图扩展。

其属于一种宏扩展形式。

NOEXPAND视图提示可强制查询优化器将视图视为带有聚集索引的普通表。

其可防止视图扩展。

只有在FROM子句中直接引用索引视图,才会应用NOEXPAND提示。

例如,

SELECTColumn1,Column2,...FROMTable1,View1WITH(NOEXPAND)WHERE...

如要确保让SQLServer通过自己读取视图而不是从基表读取数据来处理查询,那么可使用NOEXPAND。

如果出于某种原因,SQLServer选择了一个查询计划来对基表处理查询,而您想让其使用视图,那么可以考虑使用NOEXPAND。

必须在除Developer和Enterprise版本外的SQLServer的所有版本中使用NOEXPAND来让SQLServer直接对索引视图处理查询。

可以看到SQLServer为计划的图形表达式选择了一个使用SQLServerManagementStudio工具的显示预计的执行计划功能的语句。

或者,可以看到使用SHOWPLAN_ALL、SHOWPLAN_TEXT或SHOWPLAN_XML的不同的非图形表达式。

参阅SQLSever联机丛书中有关SHOWPLAN的不同版本的相关讨论。

使用EXPANDVIEWS查询提示

处理按名称引用视图的查询时,除非对视图引用添加NOEXPAND提示,否则SQLServer总会扩展视图。

该提示会尝试匹配索引视图和扩展查询,除非在查询末尾的一个OPTION子句中指定EXPANDVIEWS查询提示。

例如,假设数据库中有一个索引视图View1。

在下方的查询中,根据其逻辑定义(其CREATEVIEW语句)对View1进行了扩展,然后EXPANDVIEWS选项会阻止在计划中使用View1的索引视图来解析该查询。

SELECTColumn1,Column2,...FROMTable1,View1WHERE...

OPTION(EXPANDVIEWS)

如要确保让SQLServer通过从查询所引用的基表直接访问数据来处理该查询,而不必访问索引视图,那么可使用EXPANDVIEWS。

在某些情况下,EXPAND视图有助于消除因使用索引视图而导致的锁争用。

在测试应用程序时,NOEXPAND和EXPANDVIEWS都可帮助用户在使用和不使用索引视图的情况下进行性能评估。

返回页首

SQLServer2005的索引视图有哪些新增功能?

与SQLServer2000相比,SQLServer2005包含了许多索引视图的改进功能。

可索引的视图组已扩展至包含基于下列各项的视图:

标量聚合,包括SUM和不带GROUPBY的COUNT_BIG。

标量表达式和用户定义的功能(UDFs)。

例如,给定一个表T(aint,bint,cint)和一个标量UDFdbo.MyUDF(@xint),T上定义的索引视图可包含一个计算列(比如:

a+b或dbo.MyUDF(a))。

不精确的永久性列。

不精确的列是一种浮型或实型的列,或者是一种派生自浮型或实型列的计算列。

在SQLServer2000中,如果不属于索引键的一部分,不精确的列就可用于索引视图的选择列表。

不精确的列不能用于视图定义中的其他地方(比如:

WHERE或FROM子句)。

如果不精确的列永久保存在基表中,那么SQLServer2005允许其加入键或视图定义。

永久性列包含常规列和标记为PERSISTED的计算列。

不精确的非永久性列无法加入索引或索引视图的根本原因是:

必须使数据库脱离原计算机,然后再附加到另一台计算机。

完成转移之后,保存在索引或索引视图中的所有计算列值在新硬件上的派生方式必须与旧硬件完全相同,精确到每个位。

否则,这些索引视图在新硬件上会遭到逻辑破坏。

由于这种破坏,在新硬件上,针对索引视图的查询会根据计划是否使用了索引视图或基表来派生视图数据,返回不同的应答。

此外,无法在新计算机上正常维护索引视图。

可惜,不同计算机上的浮点硬件(即便采用相同制造商的相同处理器体系结构)在处理器的版本上并不总是完全相同。

对于某些浮点值a和b,固件升级可能导致新硬件上的(a*b)不同于旧硬件上的(a*b)。

例如,结果可能非常相近,但仍存在细微差别。

在进行索引之前一直保留不精确的计算值可解决这种分离/附加的不一致性问题,因为在进行索引和索引视图的数据库更新和维护期间,在相同的计算机上评估了所有表达式。

通用语言运行时(CLR)类型。

SQLServer2005的一个主要的新功能是支持基于CLR的用户定义的类型(UDT)和UDF。

假如列或表达式具有确定性或是永久且精确的,或者二者兼具,那么就可在CLRUDT列或从这些列派生而来的表达式上定义索引视图。

不能在索引视图上使用CLR用户定义的聚合。

优化器匹配查询和索引视图(使之可在查询计划中使用)的功能经扩展包含:

新的表达式类型,位于查询或视图的SELECT列表或条件中,涉及:

标量表达式(比如(a+b)/2)。

标量聚合。

标量UDF。

间隔归入。

优化器可检测索引视图定义中的间隔条件是否覆盖或“归入”查询中的间隔条件。

例如,优化器可确定“a>10anda<20”覆盖“a>12anda<18”。

表达式等价。

某些表达式虽然在语法上有所不同,但最终的结果却相同,那么可以将其视为等价。

例如,“a=bandc<>10”与“10<>candb=a”等价。

另外,如果数据库中存在大量索引视图,那么对比在其上定义视图的表的编译性能,SQLServer2005通常要比SQLServer2000快很多。

.

返回页首

设计注意事项

对数据库系统确定一组适当的索引可能很复杂。

如果在设计一般索引时需要考虑众多可能性,那么对架构添加索引视图会大幅提高设计和潜在结果的复杂性。

例如,索引视图可用于:

查询中引用的表的任何子集。

该表子集的查询中的条件的任何子集。

组合的列。

聚合函数(比如:

SUM)。

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

由于索引和索引视图对给定查询可能都很有用,因此分开设计会导致多余的建议,从而产生较高的存储和维护开销。

优化数据库的物理设计时,必须权衡一组不同的查询和数据库系统必须支持的更新的性能要求。

所以,对索引视图确定一项适当的物理设计是一种富有挑战性的任务,应尽可能使用数据库优化顾问(DatabaseTuningAdvisor)。

如果为建立一个特殊的查询,查询优化器考虑了许多索引视图,那么查询优化成本就会显著增加。

查询优化器可能会考虑在查询中的表的任何子集上定义的所有索引视图。

在拒绝视图之前,必须调查每个视图以便进行替换。

这可能要花一些时间,尤其当给定查询存在数百个这类视图时。

在其上创建一个唯一的聚集索引之前,视图必须满足几项要求。

在设计阶段,考虑这些要求:

视图以及视图中引用的所有表必须在相同的数据库中,并具有相同的所有者。

索引视图不必包含查询中引用的供优化器使用的所有表。

在视图上创建任何其他的索引之前,必须先创建一个唯一的聚集索引。

在创建基表、视图和索引时,以及基表和视图中的数据被修改时,必须正确设置某些SET选项(在本文档后面所有详述)。

此外,除非这些SET选项正确无误,否则查询优化器不会考虑索引视图。

必须使用架构绑定创建视图,并且还必须通过SCHEMABINDING选项创建该视图中引用的任何用户定义的函数。

需要额外的磁盘空间来保存索引视图所定义的数据。

设计方针

设计索引视图时考虑这些指导方针:

设计可供几个查询或多项操作使用的索引视图。

例如,包含列的SUM和COUNT_BIG的索引视图可供包含函数SUM、COUNT、COUNT_BIG或AVG的查询使用。

查询的速度会更快,因为只需对视图中少量的行进行检索,而不必检索基表中所有的行,而且执行AVG函数所需的一部分计算已经完成。

使索引键保持简洁。

通过在索引键中尽可能使用最少的列和字节,可对索引视图的列实现更高效的访问,因为索引视图的列更窄,键比较的速度较更宽的键快一些。

另外,在索引视图上定义的每个非聚集索引中,聚集索引键都被用作行定位器。

较大的索引键的成本随视图上非聚集索引的数量成比例增长。

考虑最终索引视图的大小。

对于纯聚合,如果索引视图的大小与原始表的大小不相上下,可能就不会实现巨大的性能改善。

设计多个较小的索引视图来局部加速过程。

可能无法总对整个查询设计一个索引视图。

如要怎么做,考虑创建若干个索引视图,各执行部分查询。

考虑这几个例子:

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

因为索引视图无法从多个数据库引用表,所以用户不能设计一个视图来执行整个过程。

但是,可以在每个数据库中创建一个索引视图来进行各个数据库的聚合操作。

如果优化器可匹配索引视图和现有的查询,那么至少聚合处理的速度会更快,同时不必对现有的查询进行重新编码。

虽然联接处理不会加快,但整个查询将变快,因为其使用存储在索引视图中的聚合。

经常执行的查询聚合来自几个表的数据,然后使用UNION合并结果。

索引视图不支持UNION。

可设计若干个视图来执行每个聚合操作。

而后,优化器可选择索引视图来加快查询,而不必对查询进行重新编码。

虽然未改进UNION处理,但改善了各个聚合过程。

有能帮助选择索引视图的工具吗?

数据库优化顾问(DTA3)是SQLServer2005的一项功能,可帮助管理员优化物理数据库设计。

除了建议使用基表上的索引以及表和索引分区策略外,DTA还推荐使用索引视图。

使用DTA可加强管理员确定索引、索引视图和分区策略(可优化对数据库执行的查询的典型组合的性能)的组合的能力。

DTA会向用户推荐广泛的索引视图。

其中包括运用SQLServer2005的索引视图的新功能(在“SQLServer2005的索引视图有哪些新增功能?

”一节有所描述)的索引视图。

DTA并没有排除让数据库管理在设计物理存储结构时做出恰当判断的需要。

但是,它可以简化物理数据库的设计过程。

DTA通过推荐一组假定的索引,索引视图和分区结果,与基于成本的查询优化器协同工作。

DTA使用优化器来估计当使用和不使用这些结构时的工作负荷成本,并推荐可提供较低的总成本的结构。

因为数据库优化顾问强制执行所有必须的SET选项(确保结果集正确无误),所以将成功完成索引视图的创建。

然而,如果未能按要求设置选项,用户的应用程序可能无法运用这些视图。

如果未按要求指定SET选项,对加入索引视图定义的表执行的插入、更新或删除操作就有可能失败。

更新数据时索引视图会有什么变化?

与其他任何索引一样,当基表数据变化时,SQLServer会自动维护索引视图。

对于一般索引,每个索引都直接与一个表相关联。

随着在基础表上执行每一项INSERT、UPDATE或DELETE操作,索引将被相应地更新,从而使保存在索引中的值总是与表保持一致。

索引视图也得到相同的维护;但是,如果视图引用了若干个表,那么更新任何一个表都需要更新索引视图。

不同于一般索引,在任何参与的表中插入一行都可能导致索引视图中发生多行更改。

这是因为所插入的行可能与另一个表的多个行相联接。

更新和删除行的情况也一样。

因此,索引视图的维护成本可能比维护表上的索引更高。

相反,维护具有高选择性条件的索引视图的成本可能要比维护表上的索引低得多,因为多数对视图所引用的基表的插入、删除和更新操作不会影响视图。

不用访问其他数据库数据就可为索引视图筛选掉这些操作。

在SQLServer中,可更新某些视图。

当某个视图可更新时,将使用INSERT、UPDATE和DELETE语句通过视图直接修改底层基表。

在视图上创建索引不会阻止视图的更新。

索引视图的更新确实会导致视图下基表的更新。

这些更新会作为索引视图维护的一部分自动传播回索引视图。

有关可更新的视图的详细信息,参阅面向SQLServer2005的SQLServer联机丛书中的“通过视图修改数据”。

维护成本注意事项

设计索引视图时应考虑下面这几点:

索引视图的数据库需要附加存储。

索引视图的结果集在物理上通过与典型表存储相似的方式保留在数据库中。

SQLServer会自动维护视图;因此,对定义了视图的基表进行的任何更改都可能引发对索引视图进行一项或多项更改。

所以,将产生额外的维护开销。

视图所获得的净性能提升为其所实现的总查询执行成本节约与存储和维护成本的差值。

比较容易获得接近于视图所需的存储。

通过SQLServerManagementStudio工具——显示预计的执行计划,评估视图定义所封装的SELECT语句。

该工具将生成查询所返回的行数和行大小的近似值。

通过将这两个值相乘,就可以获得接近于可能的视图大小;但是,只是近似。

只有在视图定义中执行查询或在视图上创建索引,才能确定视图上索引的实际大小。

从SQLServer所执行的自动维护注意事项的角度来看,显示预计的执行计划功能可能会让用户在一定程度上了解这一开销的影响。

如果通过SQLServerManagementStudio评估修改视图的语句(视图上的UPDATE、基表中的INSERT),对该语句显示的执行计划将包括该语句的维护操作。

如果就该操作在生产环境中所要执行的次数考虑该成本,那么可能会产生视图维护成本。

通常建议尽可能对视图或其底下的基表成批(而非单独)执行任何修改或更新操作。

这样就会降低视图维护开销。

返回页首

创建索引视图

创建索引视图所需的步骤对于视图的成功执行至关重要。

1.

针对将在视图中引用的所有现有表,确认ANSI_NULLS的设置正确无误。

2.

创建任何新表之前,确认对下表所示的当前会话正确设置了ANSI_NULLS。

3.

创建任何新表之前,确认对下表所示的当前会话正确设置了ANSI_NULLS和QUOTED_IDENTIFIER。

4.

确认视图定义具有确定性。

5.

使用WITHSCHEMABINDING选项创建视图。

6.

在视图上创建唯一的聚集索引之前,确认会话的SET选项的设置正确无误,如下图所示。

7.

在视图上创建唯一的聚集索引。

8.

可用OBJECTPROPERTY函数检查现有表或视图上ANSI_NULLS和QUOTED_

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1