扩大
缩小
  

十六、索引

一、索引基本概念

在数据库中建立索引是为了加快数据的查询速度。数据库中的索引与书籍中的目录或书后的术语表类
似。在一本书中,利用目录或术语表可以快速查找所需信息,而无须翻阅整本书。在数据库中,索引使
对数据的查找不需要对整个表进行扫描,就可以在其中找到所需数据。书籍的索引表是一个词语列表,
其中注明了包含各个词的页码。而数据库中的索引是一个表中所包含的列值的列表,其中注明了表中包
含各个值的行数据所在的存储位置。可以为表中的单个列建立索引,也可以为一组列建立索引。索引一
般采用B树结构。索引由索引项组成,索引项由来自表中每一行的一个或多个列(称为搜索关键字或索
引关键字)组成。B树按搜索关键字排序,可以对组成搜索关键字的任何子词条集合上进行高效搜索。
例如,对于一个由A、B、C三个列组成的索引,可以在A以及A、B和A、B、C上对其进行高效搜索。
例如,假设在Student表的Sno列上建立了一个索引(Sno为索引项或索引关键字),则在索引部分就
有指向每个学号所对应的学生的存储位置的信息,如下图。

当数据库管理系统执行一个在Student表上根据指定的Sno查找该学生信息的语句时,它能够识别该
表上的索引列(Sno),并首先在索引部分(按学号有序存储)查找该学号,然后根据找到的学号所指
向的数据的存储位置,直接检索出需要的信息。如果没有索引,则数据库管理系统需要从Student表的
第一行开始,逐行检索指定的Sno值。从数据结构的算法知识我们知道有序数据的查找比无序数据的查
找效率要高很多。
    但索引为查找所带来的性能好处是有代价的,首先索引在数据库中会占用一定的存储空间来存储索引信
息。其次,在对数据进行插入、更改和删除操作时,为了使索引与数据保持一致,还需要对索引进行相
应维护。对索引的维护是需要花费时间的。
因此,利用索引提高查询效率是以占用空间和增加数据更改的时间为代价的。在设计和创建索引时,应
确保对性能的提高程度大于在存储空间和处理资源方面的代价。

二、什么是数据页?

在数据库管理系统中,数据一般是按数据页存储的,数据页是一块固定大小的连续存储空间。不同的数
据库管理系统数据页的大小不同,有的数据库管理系统数据页的大小是固定的,比如SQL Server的数据
页就固定为8KB;
存放数据的数据页与存放索引项的数据页采用的都是通过指针链接在一起的方式连接各数据页,而且在
页头包含指向下一页及前面页的指针,这样就可以将表中的全部数据或者索引链在一起。数据页的组织
方式示意图如图6-2所示。
 

 

三、索引的存储结构及分类

索引分为两大类,一类是聚集索引(Clustered Index,也称为聚簇索引),另一类是非聚集索引
(Non-Clustered Index,也称为非聚簇索引)。聚集索引对数据按索引关键字值进行物理排序,非聚
集索引不对数据按索引关键字值进行物理排序,而只将索引关键字按值进行排序。图6-1所示的索引示
意图即为非聚集索引。在SQL Server中聚集索引和非聚集索引都采用B树结构来存储索引项,而且都包
含数据页和索引页,其中索引页用来存放索引项和指向下一层的指针,数据页用来存放数据。不同的数
据库管理系统中索引的存储结构不尽相同,本章我们主要介绍SQL Server对索引采用的存储结构。
B树结构B树(Balanced Tree,平衡树)的最上层节点称为根节点(Root Node),最下层节点称为叶节点
(Left Node)。在根节点所在层和叶节点所在层之间的层上的节点称为中间节点(Intermediate
Node)。B树结构从根节点开始,以左右平衡的方式存放数据,中间可根据需要分成许多层。 

四、 聚集索引

聚集索引的B树是自下而上建立的,最下层的叶级节点存放的是数据,因此它即是索引页,同时也是数
据页。多个数据页生成一个中间层节点的索引页,然后再由数个中间层节点的索引页合成更上层的索引
页,如此上推,直到生成顶层的根节点的索引页。生成高一层节点的方法是:从叶级节点开始,高一层
节点中每一行由索引关键字值和该值所在的数据页编号组成,其索引关键字值选取的是其下层节点中的
最大或最小索引关键字的值。

 

除叶级节点之外的其他层节点,每一个索引行由索引项的值以及这个索引项在下层节点的数据页编号组
成。
例如,设有职工(Employee)表,其包含的列有:职工号(Eno)、职工名(Ename)和所在部门
(Dept)。假设在Eno列上建有一个聚集索引(按升序排序)。(注:每个节点左上方位置的数字代表
数据页编号),其中的虚线代表数据页间的链接。
索引的使用代价
当插入或删除数据时,除了会影响数据的排列顺序外,还会引起索引页中索引项的增加或减少,系统会
对索引页进行分裂或合并,以保证B树的平衡性,因此B树的中间节点数量以及B树的高度都有可能会发
生变化,但这些调整都是数据库管理系统自动完成的,因此,在对有索引的表进行插入、删除和更改操
作时,有可能会降低这些操作的执行性能。 聚集索引对于那些经常要搜索列在连续范围内的值的查询
特别有效。使用聚集索引找到包含第一个列值的行后,由于后续要查找的数据值在物理上相邻而且有
序,因此只要将数据值直接与查找的终止值进行比较即可。 在创建聚集索引之前,应先了解数据是如
何被访问的,因为数据的访问方式直接影响了对索引的使用。如果索引建立的不合适,则非但不能达到
提高数据查询效率的目的,而且还会影响数据的插入、删除和更改操作的效率。因此,索引并不是建立
的越多越好(建立索引需要占用空间,维护索引需要耗费时间),而是要有一些考虑因素。 

聚集索引使用建议

下列情况可考虑创建聚集索引:
1. 包含大量非重复值的列。
2. 使用下列运算符返回一个范围值的查询:BETWEEN AND、>、>=、< 和 <=。
3. 经常被用作连接的列,一般来说,这些列是外键列。
4. 对ORDER BY或GROUP BY子句中指定的列建立索引,可以使数据库管理系统在查询时不必对数
据再进行排序,从而可以提高查询性能。 对于频繁进行更改操作的列则不适合建立聚集索引。

五、 非聚集索引

非聚集索引与新华字典的偏旁部首查字法类似。字典的内容(数据)存储在一个地方, (部首)存储
在另一个地方。而且字典的内容(数据)并不按部首(索引)的顺序存放,但偏旁部首中的每个词在字
典中都有确切的位置。非聚集索引就类似偏旁部首,而数据就类似于一本字典的的文字。 非聚集索引
的存储示意图如下图:

 

非聚集索引与聚集索引一样用B树结构,但有两个重要差别:
1. 数据不按非聚集索引关键字值的顺序排序和存储。
2. 非聚集索引的叶级节点不是存放数据的数据页。 非聚集索引B树的叶级节点是索引行。每个索引
行包含非聚集索引关键字值以及一个或多个行定位器,这些行定位器指向该关键字值对应的数据
行(如果索引不唯一,则可能是多行)。
例如,假设在Employee表的Eno列上建有一个非聚集索引,则数据和其索引B树的形式。 在建有非聚
集索引的表上查找数据的过程与聚集索引类似,也是从根节点开始逐层向下查找,直到找到叶级节点,
在叶级节点中找到匹配的索引关键字值之后,其所对应的行定位器所指位置即是查找数据的存储位置。
由于非聚集索引并不改变数据的物理存储顺序,因此,可以在一个表上建立多个非聚集索引。就象一本
书可以有多个术语表一样,如一本介绍园艺的书可能会包含一个植物通俗名称的术语表和一个植物学名
称的术语表,因为这是读者查找信息的两种最常用的方法

非聚集索引使用建议

在创建非聚集索引之前,应先了解数据是如何被访问的,以使建立的索引科学合理。对于下述情况可考
虑创建非聚集索引:
1. 包含大量非重复值的列。如果某列只有很少的非重复值,比如只有1和0,则不对这些列建立非聚
集索引。
2. 经常作为查询条件使用的列。
3. 经常作为连接和分组条件的列。
 
posted @ 2024-01-12 14:39  风筝遇上风  阅读(16)  评论(0编辑  收藏  举报