SQL Server 数据库索引其索引的小技巧(2)

来源:asp之家 时间:2012-07-11 15:55:02 



六、高级索引技术

l 覆盖索引:
l 索引交叉:使用多个非聚簇索引以满足查询的所有列需求(来自一个表)
l 索引连接:使用索引交叉和覆盖索引技术来避免触及基本表。
l 过滤索引:为了能够索引具有零散数据分布的字段或者稀疏的列,可以在索引上应用过滤,这样它只索引一些数据。
l 索引视图:在磁盘上将视图输出实体化

6.1、覆盖索引:
在所有为满足SQL查询不用到达基础表所需的列上建立非聚簇索引。如果查询遇到一个索引并且完全不需要引用底层数据表,那么该索引可以被认为是覆盖索引。使用INCLUDE操作符使索引编程覆盖索引,浙江存储数据和索引而不需要修改索引结构本身。
覆盖索引本身对于减少逻辑读是一种游泳的技术。在以下情况使用最好:
l 你不希望增加索引键的大小,但仍然希望有一个覆盖索引;
l 你打算索引一种不能被索引的数据类型(除了文本、ntext和图像);
l 你已经超过了一个索引的关键字列的最大数量(但是最好避免这个问题)。
1、 伪聚簇索引(Pseudoclustered index):
覆盖索引物理上顺序地组织所有索引列。从I/O角度看,没有使用包含列的覆盖索引编程一种聚簇索引,用于所有完全满足于覆盖索引中列的查询。如果查询结果集需要排序,那么覆盖索引可以用于物理地按照结果集所需的顺序维护列数据。
2、 建议:
利用覆盖索引,要注意SELECT语句中的列清单。应尽可能使用较少的列来保持小的覆盖索引键尺寸。如果索引中所有列的字节数相比表的单个数据行来说较小,而且确定利用覆盖索引的查询经常执行,那么覆盖索引是有效的。
在建立许多覆盖索引之前,考虑SQLServer如何有效和自动地使用索引交叉为查询即时创建覆盖索引。

6.2、索引交叉:
如果一个表有很多索引,那么SQLServer可以使用多个索引来执行一个查询。根据每个索引选择小的数据子集,然后执行两个子集的交叉(即只返回满足所有条件的那些行)
但在现实世界中,修改现有索引时要考虑以下问题:
l 因为各种原因,可能不允许修改现有索引;
l 现有非聚簇索引键可能已经相当宽;
l 使用现有索引的查询开销将被这个修改所影响。
为了增进一个查询的性能,SQLServer可以在表上使用多个索引,因此,考虑创建多个窄索引代替宽的索引键。
有时候,可能必须为以下原因创建一个单独的非聚簇索引:
l 重新排列现有索引中的列不被允许;
l 覆盖索引所需要的一些列不能被包含在现有的非聚簇索引中;
l 两个现有非聚簇索引中的总列数可能多余覆盖索引所需要的列数;
在这些情况下,可以在剩下的列上创建非聚簇索引。

6.3、索引连接:
索引连接是索引交叉的变种,将覆盖索引技术应用到索引交叉。如果没有单个覆盖查询的索引而多个索引一齐可以覆盖该查询。SQLServer可以使用索引连接完全满足查询而不需要转到基本表。

6.4、过滤索引:
是使用过滤器的非聚簇索引,基本上上一个where子句。用俩在可能没有很好选择性的一个或多个列上创建一个高选择性的关键字组。对于大量null值时比较适用。
过滤索引在许多方面带来回报:
l 减少索引尺寸从而增进查询效率。
l 建立更小的索引降低存储开销;
l 因为尺寸减少,降低了索引维护的成本。
过滤索引需要在访问或者创建时的一组特殊ANSI设置:
ON:ANSI_NULLS,ANSI_PADDING,ANSI_WARNINGS,ARITHABORT,CONCAT_NULL_YIELDS_NULL,QUOTED_IDENTIFIER
OFF:NUMERIC_ROUNDABORT

6.5、索引视图:
SQLServer可以在视图上创建唯一的聚簇索引来磁盘上实体化。这样的索引成为索引视图或实体化视图。在创建以后可以创建非聚簇索引。
1、 好处:
l 聚合可以预先计算并被保存在索引视图中,以在查询执行期间最小化昂贵的计算;
l 表可以预先连接,结果集可以实物化;
l 连接或聚合的组成可以被实物化。

2、 开销:
l 基本表中的任何修改必须执行事务的select语句反映到索引视图中;
l 对索引视图定义的基本表上的任何修改可能发起索引视图的非聚簇索引中的修改,如果聚簇键被更新,聚簇索引也将必须更新;
l 索引视图增加数据库的维护开销;
l 数据库中需要更多的存储;
创建索引视图包括如下限制:
l 视图的第一个索引必须是唯一聚簇索引。
l 索引视图上的非聚簇索引只可以在唯一聚簇索引创建之后创建。
l 视图定义必须是确定性的——即,它对一个给定的查询只能返回一个可能的结果;
l 索引视图必须只引用相同数据库中的基本表,而不是其他视图;
l 索引视图可以包含浮点列但是这样的列不能包含在聚簇索引键中;
l 索引视图必须是绑定到列所引用表的一个架构,以免表架构的修改;
l 视图定义的语法有很多限制
l 必须确定的SET选项列表:
ON:ARITHABORT,CONCAT_NULL_YIELDS_NULL,ANSI_NULLS,ANSI_PADDING和ANSI_WARNING
OFF:NUMERIC_ROUNDABORT

3、 使用环境:
OLAP能从索引视图中获益,OLTP就比较难从中获益。


6.6、索引压缩:
从2008引入。压缩索引能造成重大性能改进,但是也会造成CPU和内存开销。不是适合所有索引的方案。
默认情况下,索引不会被压缩。必须明确地在创建索引时要求索引被压缩。分为行级和页级压缩。索引中的非叶子页面不接受页面类型下的压缩。

七、特殊索引类型

7.1、全文索引:
对文本型的字段索引
7.2、空间索引:
对于空间类型的数据进行索引
7.3、XML:
从2005引入XML后,对XML类型

八、索引的附件特性

8.1、不同的列排序顺序:
可对一个索引中的不同列进行升降序排列。
8.2、在计算列上的索引:
可以在计算列上创建索引,只要计算列的表达式符合一定的限制,比如来源表是确定的。
8.3、BIT数据类型列上的索引:
创建在BIT数据列上的索引本身不是很好的优点,但是对于覆盖索引,当涵盖了BIT列时就很有用。
8.4、作为一个查询处理的CREATE INDEX语句:

8.5、并行索引创建:
可以在max degree of parallelism配置参数来控制CREATE INDEX语句中的处理器数量,也可以使用exec sp_configure ‘maxdegree of parallelism'
8.6、在线索引创建:
可以在创建索引时减少锁的机会。
8.7、考虑数据库引擎调整顾问

九、小结

为了决定特殊查询的索引键列,需要评估查询的WHERE子句和连接条件。像列选择性、宽度、数据类型和列顺序这些因素。因为索引主要是为了检索少量行,所以索引选择性必须非常高。
为了获得更好性能,尝试使用覆盖索引完全覆盖查询。

SQL Server数据库优化其索引的小技巧

关于索引的常识:影响到数据库性能的最大因素就是索引。由于该问题的复杂性,我只可能简单的谈谈这个问题,不过关于这方面的问题,目前有好几本不错的书籍可供你参阅。我在这里只讨论两种SQL Server索引,即clustered索引和nonclustered索引。当考察建立什么类型的索引时,你应当考虑数据类型和保存这些数据的column。同样,你也必须考虑数据库可能用到的查询类型以及使用的最为频繁的查询类型。

索引的类型
如果column保存了高度相关的数据,并且常常被顺序访问时,最好使用clustered索引,这是因为如果使用clustered索引,SQL Server会在物理上按升序(默认)或者降序重排数据列,这样就可以迅速的找到被查询的数据。同样,在搜寻控制在一定范围内的情况下,对这些column也最好使用clustered索引。这是因为由于物理上重排数据,每个表格上只有一个clustered索引。

与上面情况相反,如果columns包含的数据相关性较差,你可以使用nonculstered索引。你可以在一个表格中使用高达249个nonclustered索引——尽管我想象不出实际应用场合会用的上这么多索引。

当表格使用主关键字(primary keys),默认情况下SQL Server会自动对包含该关键字的column(s)建立一个独有的cluster索引。很显然,对这些column(s)建立独有索引意味着主关键字的唯一性。当建立外关键字(foreign key)关系时,如果你打算频繁使用它,那么在外关键字cloumn上建立nonclustered索引不失为一个好的方法。如果表格有clustered索引,那么它用一个链表来维护数据页之间的关系。相反,如果表格没有clustered索引,SQL Server将在一个堆栈中保存数据页。

数据页
当索引建立起来的时候,SQLServer就建立数据页(datapage),数据页是用以加速搜索的指针。当索引建立起来的时候,其对应的填充因子也即被设置。设置填充因子的目的是为了指示该索引中数据页的百分比。随着时间的推移,数据库的更新会消耗掉已有的空闲空间,这就会导致页被拆分。页拆分的后果是降低了索引的性能,因而使用该索引的查询会导致数据存储的支离破碎。当建立一个索引时,该索引的填充因子即被设置好了,因此填充因子不能动态维护。

为了更新数据页中的填充因子,我们可以停止旧有索引并重建索引,并重新设置填充因子(注意:这将影响到当前数据库的运行,在重要场合请谨慎使用)。DBCC INDEXDEFRAG和DBCC DBREINDEX是清除clustered和nonculstered索引碎片的两个命令。INDEXDEFRAG是一种在线操作(也就是说,它不会阻塞其它表格动作,如查询),而DBREINDEX则在物理上重建索引。在绝大多数情况下,重建索引可以更好的消除碎片,但是这个优点是以阻塞当前发生在该索引所在表格上其它动作为代价换取来得。当出现较大的碎片索引时,INDEXDEFRAG会花上一段比较长的时间,这是因为该命令的运行是基于小的交互块(transactional block)。

填充因子
当你执行上述措施中的任何一个,数据库引擎可以更有效的返回编入索引的数据。关于填充因子(fillfactor)话题已经超出了本文的范畴,不过我还是提醒你需要注意那些打算使用填充因子建立索引的表格。

在执行查询时,SQL Server动态选择使用哪个索引。为此,SQL Server根据每个索引上分布在该关键字上的统计量来决定使用哪个索引。值得注意的是,经过日常的数据库活动(如插入、删除和更新表格),SQL Server用到的这些统计量可能已经“过期”了,需要更新。你可以通过执行DBCC SHOWCONTIG来查看统计量的状态。当你认为统计量已经“过期”时,你可以执行该表格的UPDATE STATISTICS命令,这样SQL Server就刷新了关于该索引的信息了。

建立数据库维护计划
SQL Server提供了一种简化并自动维护数据库的工具。这个称之为数据库维护计划向导(Database Maintenance Plan Wizard ,DMPW)的工具也包括了对索引的优化。如果你运行这个向导,你会看到关于数据库中关于索引的统计量,这些统计量作为日志工作并定时更新,这样就减轻了手工重建索引所带来的工作量。如果你不想自动定期刷新索引统计量,你还可以在DMPW中选择重新组织数据和数据页,这将停止旧有索引并按特定的填充因子重建索引。

标签:SQLServer,数据库索引
0
投稿

猜你喜欢

  • 分享10个Js的小型库,效果真的很棒

    2009-08-27 15:38:00
  • 使用Javascript面向对象的思想编写ASP

    2008-06-16 12:20:00
  • ASP教程:制作登陆验证页面程序

    2008-10-23 15:00:00
  • Excel和Access之间的数据交换

    2008-11-20 16:53:00
  • SQL Server2000的安全策略

    2007-08-06 17:14:00
  • JavaScript 中的 setAttribute

    2008-08-18 13:08:00
  • xhtml+css VS div+css

    2008-04-07 13:00:00
  • 纯CSS图片预加载

    2009-10-28 18:40:00
  • ASP程序中调用函数Now()显示上午下午的问题

    2009-08-27 13:09:00
  • 关于textarea的直观换行

    2010-03-18 15:59:00
  • 设计者在网页排版中应注意的一些问题

    2012-04-20 13:13:58
  • ASP保存远程图片到本地 同时取得第一张图片并创建缩略图的代码

    2011-04-19 11:07:00
  • ACCESS转SQL Server2000需要注意的问题

    2007-11-18 15:25:00
  • ASP访问带多个参数的存储过程

    2008-10-14 16:45:00
  • 间歇向上无缝翻滚代码

    2008-05-05 12:30:00
  • mysql出现10061错误解决办法

    2010-07-04 13:36:00
  • 自定义用于ASP Web站点的 SQL 7.0 数据库

    2008-10-28 21:09:00
  • 分享13款非常有用的jQuery插件

    2011-05-16 19:07:00
  • SQL Server的BUILTIN\\Administrators用户

    2009-02-04 13:51:00
  • ASP同一站点下gb2312和utf-8页面传递参数乱码的终极解决方法

    2011-02-20 11:00:00
  • asp之家 网络编程 m.aspxhome.com