SQL Server 查询优化(3)_索引的设计与使用

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、索引的作用

1、帮助检索数据;

2、提高联接效率;

3、节省ORDER BY、GROUP BY的时间;

4、保证数据唯一性(仅限于唯一索引)。

二、索引的设计

在确定要建立一个索引时,首先我们要确定它是聚集还是非聚集、单列还是多列、唯一还是非唯一、列是升序还是降序、它的存储是如何的,比如:分区、填充因子等。下面逐条来看:1、聚集索引

(1)首先指出一个误区,主键并不一定是聚集索引,只是在SQL SERVER中,未明确指出的情况下,默认将主键定义为聚集,而ORACLE中则默认是非聚集,因为SQL SERVER中的ROWID未开放使用。

(2)聚集索引适合用于需要进行范围查找的列,因为聚集索引的叶子节点存放的是有序的数据行,查询引擎可根据WHERE中给出的范围,直接定位到两端的叶子节点,将这部分节点页的数据根据链表顺序取出即可;

(3)聚集索引尽量建立在值不会发生变更的列上,否则会带来非聚集索引的维护;

(4)尽量在建立非聚集索引之前建立聚集索引,否则会导致表上所有非聚集索引的重建;(5)聚集索引应该避免建立在数值单调的列上,否则可能会造成IO的竞争,以及B树的不平衡,从而导致数据库系统频繁的维护B树的平衡性。聚集索引的列值最好能够在表中均匀分布。

2、非聚焦索引

(1)非聚集索引适合用于需要进行等值查找的列,因为非聚集索引的叶子节点存放的是有序的索引列与书签的映射行,查询引擎可根据WHERE中给出的值,得到书签,继而定位到数据行;

(2)覆盖索引(Covering Index),是非聚集索引的一种特殊且高效的应用,就是将需要返回的数据列设计成组合索引,在SELECT时只查询索引中存在的数据列,这样就能形成索引覆盖,因为索引行中已经包含了想到的数据,不需要再进行书签查找;

在SQL SERVER 2005及以上版本中,提供了INCLUDED关键字,可以在非聚集索引中包含更多列,也是覆盖索引的一个有效引申;

(3)非聚集索引建立在值具有单调性的列上,比如:自增列(单调递增),可以减少索引的外部碎片及索引结构的维护;

3、复合索引

(1)复合索引建立在多个列上。上面已经讲过,在非聚集索引中,可以利用覆盖索引来提高检索的效率,但如果组合索引的列太多的话,那么对于这个索引的维护成本也会加大,DML的效率将会下降,而且索引的查找路径会变长;

(2)在创建复合索引时,应该将高选择性的列放在前面,即作为引导列;

4、唯一索引

(1)再指出一个误区,聚集索引并不一定是唯一索引,由于SQL SERVER将主键默认定义

为聚集索引,事实上,索引是否唯一与是否聚集是不相关的,聚集索引可以是唯一索引,也可以是非唯一索引;

(2)将索引设置为唯一,对于等值查找是很有利的,当查到第一条符合条件的纪录时即可停止查找,返回数据,而非唯一索引则要继续查找,同样,由于需要保证唯一性,每一行数据的插入都会去检查重复性;

5、分区索引

(1)SQL SERVER从2005引入的分区表的概念,对于在分区表上建立的索引,无论是否包含分区列,在未指定分区方案或文件组的情况下,均会使用分区表的分区方案来创建该索引。这一点与ORACLE正好相反;

6、其他索引

(1)筛选索引,在ORACLE中叫域索引,这是SQL SERVER 2008新增的功能,适用于表中数据密度不高的列来创建索引,比如:表中某列大多是NULL或某相同值,那么此时可通过WHERE关键字来筛选这些相同值来创建索引,这样在对非相同的值进行检索时,即可以用到这个索引;

(2)计算列索引,在ORACLE中叫函数索引,如果表中存在计算列,但想要对计算列进行检索,可在计算列上创建索引,但前提是必须要先持久化该计算列;

(3)索引视图,在ORACLE中叫物化视图,我们知道视图的数据都是来源于基础表,在SQL SERVER中对视图建立索引,事实上就对视图进行了物化,然后才创建索引,索引视图多用于静态数据的查询,毕竟物化视图的更新是比较麻烦的;

(4)位图索引,对BOOL型字段建立索引,在SQL SERVER中暂未提供这样的功能;(5)XML索引,对XML列只能创建XML索引;

(6)全文索引,LOB类型列上无法建立普通索引,比如V ARCHAR(MAX)、TEXT、IMAGE,如果需要检索可以考虑建立全文索引,当然全文索引也可以用在非LOB类型的列上;

7、索引参数

(1)填充因子,索引的叶子节点的填充程序,预留一定的页空间,以避免过多的页拆分,但如果预留空间太大,会放大查询的成本。对于索引的中间节点如果也使用填充因子可以打开PAD_INDEX选项;

(2)忽略重复键,这个选项通常用于去重处理,对于将要插入到表中的行,如果存在相同索引键,则抛弃;

(3)根据业务查询需要,决定列升序还是降序,通常对于单列索引存在正向或反向扫描,但在复合索引的非引导列中检索时,如果存在需要倒排的查询,则在建立索引时应选择降序;(4)在索引的存储上,将聚集和非聚集索引定义在不同磁盘分区的文件组上,减少IO竞争,亦可利用多CPU并发,但目前通常都是RAID5+1(1备份5中的一块硬盘)的存储,数据存放本就已分散,这样做的意义并不是太大。

8、索引列选择

(1)参考[索引的作用]选择索引列,比如:如果表中存在外键,考虑在该列上建立索引,可增加参照完整性检查的速率,同样,如果存在连接,也可提高连接的速率;

(2)索引选择性公式:selectivity=unique keys/rows,一般当选择性低于0.1即10%时,查询优化器拒绝使用该索引,比如:BOOL类型的列。此处有一个矛盾,有可能我们无法知道当前列的selectivity,那么只能采用估算的方式,比如采用SQL SERVER 2005的

相关文档
最新文档