
第5章索引及其应用 41索引的概述 41.1引例 1.为什么要使用索引 为了方便理解索引,我们先来看看书霜中的目录,在一本书中,利用目录可以快速查找 到相关信息,而无须阅读整本书。这是因为书的目录包含了一系列条目,每个条日注明了内 容标注和具体的页码。数据库入目录机制,就可以快速定位表中数据行的某线列组合成数 据行的目录”,以后在查海扫描量据表之输先到宽这些“数据行的目录“,就可以大大加快数 据查询的时间。 在数据库中,数据的查面就是对数据表进行扫描。如果没有素引,就雷要一行一行的扫 描整个数据表,势必查询花费的时阿较长:如果将数据表中的某些列(例如主键)制作成素引, 查询数据的时候先查看一下素引而不扫描整个数据表,这相当于先能翻书籍的目录。从素引 里确定了用户要查找的数据在表中哪些行里面,再去扫描这些行,查面的速度会大大加快, 使得SQLServer系统的性能得以提高. 用户对数据库最基本、最顿繁的操作是数据查询。一般情况下,查询数据时需要浏览整 个表米搜索数据,当表中的数据很多时,搜索数据需要很长时间。因此,为了如快查询速度 诚少服务器的响应时间,数据库系统引入了索州机制: 2使用需引的代价 素引是以数据表的列为基础建立的数据库对象,它保存着表中排序的索引列,并且记录 了索引列在数据表中的物理存销位置,实现了表中数据的逻帽排序,它是由一行行的记录组 成,每一行记录都包含数据表中一列城若干列值的集合和相应指向表中爱据页的度辑指针。 由于素引包含了表中的都分数据以及记录这些数据的地址指针,因此索引能大大加愤在面速 度。素引除了可以提高查询表内数据的速度以外,使表和表之间的连接速度加快,特别是在 实现数据的参照完整性。可以将表的外键制作成素引,这样将加速表与表之问的连找。 虽然索到具有如此之多的优点,但素引的存在也让系统付出一定的代价。本身创建索引 和维护索引都会耗贵时间,当对表中的数据进行增加、酬除和修政的时候。索引就要进行操 护,否则索引的作用就会下降:另外,每个素引都会占用一定的物理空间,如果占有的物理 空间过多,就会影响到整个SQLServer系统的性能. 3建立需引的思路
第 5 章 索引及其应用 4.1 索引的概述 4.1.1 引例 1.为什么要使用索引 为了方便理解索引,我们先来看看书籍中的目录,在一本书中,利用目录可以快速查找 到相关信息,而无须阅读整本书。这是因为书的目录包含了一系列条目,每个条目注明了内 容标注和具体的页码。数据库引入目录机制,就可以快速定位表中数据行的某些列组合成“数 据行的目录”,以后在查询扫描数据表之前先浏览这些“数据行的目录”,就可以大大加快数 据查询的时间。 在数据库中,数据的查询就是对数据表进行扫描。如果没有索引,就需要一行一行的扫 描整个数据表,势必查询花费的时间较长;如果将数据表中的某些列(例如主键)制作成索引, 查询数据的时候先查看一下索引而不扫描整个数据表,这相当于先翻翻书籍的目录,从索引 里确定了用户要查找的数据在表中哪些行里面,再去扫描这些行,查询的速度会大大加快, 使得 SQLServer 系统的性能得以提高。 用户对数据库最基本、最频繁的操作是数据查询。一般情况下,查询数据时需要浏览整 个表来搜索数据,当表中的数据很多时,搜索数据需要很长时间。因此,为了加快查询速度、 减少服务器的响应时间,数据库系统引入了索引机制。 2.使用索引的代价 索引是以数据表的列为基础建立的数据库对象,它保存着表中排序的索引列,并且记录 了索引列在数据表中的物理存储位置,实现了表中数据的逻辑排序。它是由一行行的记录组 成,每一行记录都包含数据表中一列或若干列值的集合和相应指向表中数据页的逻辑指针。 由于索引包含了表中的部分数据以及记录这些数据的地址指针,因此索引能大大加快查询速 度。索引除了可以提高查询表内数据的速度以外,使表和表之间的连接速度加快,特别是在 实现数据的参照完整性。可以将表的外键制作成索引,这样将加速表与表之间的连接。 虽然索引具有如此之多的优点,但索引的存在也让系统付出一定的代价。本身创建索引 和维护索引都会耗费时间,当对表中的数据进行增加、删除和修改的时候,索引就要进行维 护,否则索引的作用就会下降;另外,每个索引都会占用一定的物理空间,如果占有的物理 空间过多,就会影响到整个 SQLServer 系统的性能。 3.建立索引的思路

素引虽燃可以提高查面速度,但是它雷要牺鞋一定的系统性能。因此创建累引时,事些 列适合创建素引,愿生列不适合创建索明,需要进行一番判断考察才能进行素引的创建, ()定义有主键的列要建立索引。因为主健可以惟一表示行,通过主键可以快速定位到表 中的某一行。 ()定义有外键的列可以建立索引,外健的列通常用于数据表与数据表之间的连接,在其 上创建索引可以加快数据表间的连接。 (3)在经常查询的列最好建立索引。 ①需要在指定范围内快速或频繁查询的列,因为索引已经排序,其指定的范围是连续的, 查询可以利用索引的排序,加快排序查询的时间。 ②经常用在证E子句的列,将索引建立在E字句的集合过程中需要快速或顿繁检 索的列。可以让这些经常参与查询的列按照索引的排序进行查询。加快查询时间。 ()对于那丝查诸中很少涉及的列、重复值比较多的列不要建素引,例如,在查询中很少 使用的列,有无索引并不能提高查面速度,相反增加了系统维护时间和消耗了系统空间:又 如,性别列只有列值“男”和“女”,增加索引并不能显著提高查淘速度。 (⑤对于定义为10xt,1国m和b1t数据类型的列上不要建立素引,因为数据类型为1ext、 ntext或i的数据列的数据量要么很大,要么很小,不利于使用索引。 4.1,2素引中数据的存储 前面讲过,索引中包含表中部分数据和数据的地址,为了设计好索引、使用好索引,需 要搞清楚索引的数据结构和数据存储。 第2章讲过SQLServer205的数据文件由一些8B大小数据页组成.SqL5ener2005中 共有8种数据页,而索引是其中的一种。 1.堆结构 当向数据库中括入数据的时候,数据是按照括入的时间顺序被放置在数据页上。一般地, 放置数据的顺序与数据本身的逻相关系之间并没有任何联系:因此,从数据之间的逻相关系 方面米讲,数据是乱七八槽地堆成在一起的,即逻辑上相忽的数据行物理上并不相邻。数据 的这种堆收方式称为“堆”。当一个数据页上的数据堆满之后,其它的数据瓷蝶放在另外一 个爱据页上。 SQLServer2005中,在没有建立索引的表内,使用堆的方法组织数据页。堆文件执行插 入操作根容易。但查询效率不高,因为在堆中。数据行不按任何顺序进行存储。数据真也没 有任何顺序,堆文件只能执行顺序扫描,因此扫描这些数据堆花费的时间较长。如果表内建
索引虽然可以提高查询速度,但是它需要牺牲一定的系统性能。因此创建索引时,哪些 列适合创建索引,哪些列不适合创建索引,需要进行一番判断考察才能进行索引的创建。 ⑴定义有主键的列要建立索引。因为主键可以惟一表示行,通过主键可以快速定位到表 中的某一行。 ⑵定义有外键的列可以建立索引。外键的列通常用于数据表与数据表之间的连接,在其 上创建索引可以加快数据表间的连接。 ⑶在经常查询的列最好建立索引。 ①需要在指定范围内快速或频繁查询的列。因为索引已经排序,其指定的范围是连续的, 查询可以利用索引的排序,加快排序查询的时间。 ②经常用在 WHERE 子句的列,将索引建立在 WHERE 字句的集合过程中需要快速或频繁检 索的列,可以让这些经常参与查询的列按照索引的排序进行查询,加快查询时间。 ⑷对于那些查询中很少涉及的列、重复值比较多的列不要建索引。例如,在查询中很少 使用的列,有无索引并不能提高查询速度,相反增加了系统维护时间和消耗了系统空间;又 如,性别列只有列值“男”和“女”,增加索引并不能显著提高查询速度。 ⑸对于定义为 text,image 和 bit 数据类型的列上不要建立索引。因为数据类型为 text、 ntext 或 image 的数据列的数据量要么很大,要么很小,不利于使用索引。 4.1.2 索引中数据的存储 前面讲过,索引中包含表中部分数据和数据的地址,为了设计好索引、使用好索引,需 要搞清楚索引的数据结构和数据存储。 第 2 章讲过 SQLServer2005 的数据文件由一些 8KB 大小数据页组成。SQLServer2005 中 共有 8 种数据页,而索引是其中的一种。 1.堆结构 当向数据库中插入数据的时候,数据是按照插入的时间顺序被放置在数据页上。一般地, 放置数据的顺序与数据本身的逻辑关系之间并没有任何联系;因此,从数据之间的逻辑关系 方面来讲,数据是乱七八糟地堆放在一起的,即逻辑上相邻的数据行物理上并不相邻。数据 的这种堆放方式称为“堆”。当一个数据页上的数据堆满之后,其它的数据就堆放在另外一 个数据页上。 SQLServer2005 中,在没有建立索引的表内,使用堆的方法组织数据页。堆文件执行插 入操作很容易,但查询效率不高。因为在堆中,数据行不按任何顺序进行存储,数据页也没 有任何顺序,堆文件只能执行顺序扫描,因此扫描这些数据堆花费的时间较长。如果表内建

有索引。数据行虽然杂乱,但是数据行的地址数记录在索引里面,可以说数据行是基于素引 顺序存放的。把索引看作书的目录,通过目录查找书中的信息,显然比没有目录的书方便, 快捷,尽管书的内容是按型堆结构来组织的。 2B树结构 需引包含的地址所指向的数据是按照堆的方式来组织的,那么素引的数据又是如何组织 的呢?SQLServer2006中素引的数据是按愿B树(B-Tree)米组织的。如图41所示。 图4-1B树结构 B树结构中,索引分缓组成一樱树,最上层的索引节点称为根节点,中间节点按照索引 数据量分成不同的层次,最下层的素引节点称为叶节点,素引上层节点指向下层节点,叶节 点指向数据页。素引列的宽度越大,B树的深度就越深,即层次感多,数据查询的性能将面 索引列层次数目的增如而降低。 B树素引的所有节点结构相同。每个节点都包含其它所有节点的索引码值和地址指针, 这样B树的根节点到任何一个叶节点的距离均一样长。因此,B树结构素引查面任何一个数 据页的速度均是一样的。各叶节点按照素引碍值顺序排列威接在一起,叶节点又指向最据页 节点,这样可以对文件进行高效顺序处理,又能对文件进行高效随机处理, 4.1,3零引的分类 SQLServer2006中有两种类型的索明,它们分别是聚集素引(Clustered1ndex)和非聚集 素引onclustered1ndex),它门都可以对多个列遗行素引。SOLServer2005还支持惟一索 引、素引视图和全文素引。下面先介绍丰聚集素引。 1.非聚集素引 如图42所示,非聚集素明与图书中的目豪类似。数据存他在一个地方,而素明存储在 另一个地方,同时素引带有指针所指向数据的存储地址。非聚集索引顺序与数据的物理存储 顺序不一政,索引中的项川按索引健值的顺序存储,而表中的数据按操作系统指定的物理存 储顺序存储。 图42非聚集索引 SQL.Server2005在查面数据时,先对非聚集索月送行复索,找到数据在表中的位置,然 后根据素引所提供的数据位置信息。到磁盘上的该位置处读取数据。 丰聚集素引是B树结构,它的叶节点包含数据行,每个数据行包含非聚集索引键值以及 一个或多个行定位器,这些行定位器指向有该键值的数据行〔如果索引不惟一,则可使指向 多行)
有索引,数据行虽然杂乱,但是数据行的地址被记录在索引里面,可以说数据行是基于索引 顺序存放的。把索引看作书的目录,通过目录查找书中的信息,显然比没有目录的书方便、 快捷,尽管书的内容是按照堆结构来组织的。 2.B 树结构 索引包含的地址所指向的数据是按照堆的方式来组织的,那么索引的数据又是如何组织 的呢?SQLServer2005 中索引的数据是按照 B 树(B-Tree)来组织的。如图 4-1 所示。 图 4-1B 树结构 B 树结构中,索引分级组成一棵树,最上层的索引节点称为根节点,中间节点按照索引 数据量分成不同的层次,最下层的索引节点称为叶节点。索引上层节点指向下层节点,叶节 点指向数据页。索引列的宽度越大,B 树的深度就越深,即层次越多,数据查询的性能将随 索引列层次数目的增加而降低。 B 树索引的所有节点结构相同,每个节点都包含其它所有节点的索引码值和地址指针, 这样 B 树的根节点到任何一个叶节点的距离均一样长,因此,B 树结构索引查询任何一个数 据页的速度均是一样的。各叶节点按照索引码值顺序排列链接在一起,叶节点又指向数据页 节点,这样可以对文件进行高效顺序处理,又能对文件进行高效随机处理。 4.1.3 索引的分类 SQLServer2005 中有两种类型的索引,它们分别是聚集索引(ClusteredIndex)和非聚集 索引(NonclusteredIndex),它们都可以对多个列进行索引。SQLServer2005 还支持惟一索 引、索引视图和全文索引。下面先介绍非聚集索引。 1.非聚集索引 如图 4-2 所示,非聚集索引与图书中的目录类似。数据存储在一个地方,而索引存储在 另一个地方,同时索引带有指针所指向数据的存储地址。非聚集索引顺序与数据的物理存储 顺序不一致,索引中的项目按索引键值的顺序存储,而表中的数据按操作系统指定的物理存 储顺序存储。 图 4-2 非聚集索引 SQLServer2005 在查询数据时,先对非聚集索引进行搜索,找到数据在表中的位置,然 后根据索引所提供的数据位置信息,到磁盘上的该位置处读取数据。 非聚集索引是 B 树结构,它的叶节点包含数据行,每个数据行包含非聚集索引键值以及 一个或多个行定位器,这些行定位器指向有该键值的数据行(如果索引不惟一,则可能指向 多行)

2案集素(ClusteredIndex) 聚集索引中索引存销的值的顺序和表中数据的物理存铺顺序完全一致。建立素引时,系 统将对表的物理数据页中的数据按列进行排序(注意,数据的物理位置发生了移动,这一点 是与丰聚集索引的关健区别),然后再重新存储到磁盘上,即聚集素引与数据是混为一体的, 聚集素引的叶节点中存储的是实际的数据。 常见得新华字典的正文本身就是一个聚集索引。比如,要查“安”字,就会根自然地题 开字奥的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字具是以英文字母“” 开头并以“x”结尾的。那么“安”字就白燃地持在字典的前都。同样的。如果查“张”字, 那您也会将您的字典翻到最后部分,因为“张”的拼音是“zag”。也就是说,字典的正文 部分本身就是一个川录,您不需要再去查其他川录来找到您需要找的内容。我们把这种正文 内容本身就是一种按照一定规则挂列的目柔称为“聚集素可引”。日常生活中的电话本也是一 种聚集索引。 紧集索对于那些经常要搜索范围值的列特别有效。使用聚集素引找到包含第一个值的 行后,便可以确保包含后铁素引值的行物理相忽。如图43所示。 图4-3聚集素引 显然,聚集索引的查询速度比幸素集需引快,但非聚集索引的谁护比较容易,究竟该使 用哪种索引?表】的内容进行了一个总结。 表41使用紧集索引或非紧集索引 动作描述 使用聚集素引 使用非聚集索引 列经常被分组挂序 返回某蔻围内的数据 一个或极少不羽值 小数目的不同值 大数目的不同值 烦繁更新的列 外健列 主健列 烦繁修政索引列
2.聚集索引(ClusteredIndex) 聚集索引中索引存储的值的顺序和表中数据的物理存储顺序完全一致。建立索引时,系 统将对表的物理数据页中的数据按列进行排序(注意,数据的物理位置发生了移动,这一点 是与非聚集索引的关键区别),然后再重新存储到磁盘上,即聚集索引与数据是混为一体的, 聚集索引的叶节点中存储的是实际的数据。 常见得新华字典的正文本身就是一个聚集索引。比如,要查“安”字,就会很自然地翻 开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a” 开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。同样的,如果查“张”字, 那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文 部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。我们把这种正文 内容本身就是一种按照一定规则排列的目录称为“聚集索引”。日常生活中的电话本也是一 种聚集索引。 聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的 行后,便可以确保包含后续索引值的行物理相邻。如图 4-3 所示。 图 4-3 聚集索引 显然,聚集索引的查询速度比非聚集索引快,但非聚集索引的维护比较容易。究竟该使 用哪种索引?表 4-1 的内容进行了一个总结。 表 4-1 使用聚集索引或非聚集索引 动作描述 使用聚集索引 使用非聚集索引 列经常被分组排序 返回某范围内的数据 一个或极少不同值 小数目的不同值 大数目的不同值 频繁更新的列 外键列 主键列 频繁修改索引列

事实上,可以通过前面聚集索引和非聚集素明的定义的例子来理解上表。如:返回某范 围内的数据一项。比如某个表有一个时间列,恰好把繁集素引建立在了该列,这时查询2004 年1月1日至004年10月1日之间的全部数据时,这个速度就将是很快的,因为这本字典 正文是按日期进行排序的,聚类赛引只需要找到要检的所有数据中的开头和结尾数据即 可:而不像非繁集索引。必须先查到川录中查到每一项数据对应的真码,然后再根据页码查 到具体内容。 3惟一索引 惟一索是指索引值必领是惟一的。在创建表时,建文了主键,则SQL.Server2O06就会 默认建立一个性一素引。 聚集索引和非聚集索明是从索引量据存销的角度来区分的:而惟一索引和非惟一索引是 从索引取值米区分的。所以,惟一索引和非推一索引战可以是聚集索引,也可以是非聚集索 引,只要列中的数据是惟一的,就可以在同一张表上创建一个整一的聚集素引和多个惟一的 非聚集索引。 4索引视图 数据企库应用程序中轻常会遇到复索服表的情形,当这些查询访问视图时,尤其是视图 涉及到复桑象的大量行处理,如大量数据聚合或多表联接,这一操作的开销较大,系统的性能 会下降。 针对这种情形,S5 erver2005允许为视图侧建独特的聚集素引,从而让访问此类视图 的查面性能得以极大的改雾。当创建了这样一个素引后,视图将被执行,结果集将技存放在 数据库中,存放的方式与带有聚集索引的表的存放方式相同.这就在数据库中有效地实现了 查询结果。 如果在祝图上创建索引,那么视图中的数据会被立即存储在数据库中,对索引祝图进行 修改,那么这些修改会立即反缺到基础表中。同理,对基础表所进行的数据修改也会反映到 索引视图中,索引的惟一性大大提高了S网Sver查找些技修改的数据行的速度, 5全文需引 全文素明可以对存储在SQLServer数据库中的文本数据进行快遮检素功能。同LIE谓 司不同。全文素引只对字符慎式进行操作,对字和语句执行搜素功能。全文素引对于查面非 结构化数据季常有效。一般情况下,可以对char、varchar和nvarchar数据类型的列创建 全文素引,同时,还可以对二进制格式的列创建素引,如1e和varbinar四数据类型列, 使用LE酬问无法对这些二进制爱据执行搜素
事实上,可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如:返回某范 围内的数据一项。比如某个表有一个时间列,恰好把聚集索引建立在了该列,这时查询 2004 年 1 月 1 日至 2004 年 10 月 1 日之间的全部数据时,这个速度就将是很快的,因为这本字典 正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即 可;而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查 到具体内容。 3.惟一索引 惟一索引是指索引值必须是惟一的。在创建表时,建立了主键,则 SQLServer2005 就会 默认建立一个惟一索引。 聚集索引和非聚集索引是从索引数据存储的角度来区分的;而惟一索引和非惟一索引是 从索引取值来区分的。所以,惟一索引和非惟一索引既可以是聚集索引,也可以是非聚集索 引,只要列中的数据是惟一的,就可以在同一张表上创建一个惟一的聚集索引和多个惟一的 非聚集索引。 4.索引视图 数据仓库应用程序中经常会遇到复杂报表的情形。当这些查询访问视图时,尤其是视图 涉及到复杂的大量行处理,如大量数据聚合或多表联接,这一操作的开销较大,系统的性能 会下降。 针对这种情形,SQLServer2005 允许为视图创建独特的聚集索引,从而让访问此类视图 的查询性能得以极大的改善。当创建了这样一个索引后,视图将被执行,结果集将被存放在 数据库中,存放的方式与带有聚集索引的表的存放方式相同。这就在数据库中有效地实现了 查询结果。 如果在视图上创建索引,那么视图中的数据会被立即存储在数据库中,对索引视图进行 修改,那么这些修改会立即反映到基础表中。同理,对基础表所进行的数据修改也会反映到 索引视图中,索引的惟一性大大提高了 SQLServer 查找那些被修改的数据行的速度。 5.全文索引 全文索引可以对存储在 SQLServer 数据库中的文本数据进行快速检索功能。同 LIKE 谓 词不同,全文索引只对字符模式进行操作,对字和语句执行搜索功能。全文索引对于查询非 结构化数据非常有效。一般情况下,可以对 char、varchar 和 nvarchar 数据类型的列创建 全文索引,同时,还可以对二进制格式的列创建索引,如 image 和 varbinary 数据类型列。 使用 LIKE 谓词无法对这些二进制数据执行搜索

SQLServer中有两种类型的素引,它们分别是聚集索引C1 usteredInde)和非聚集索引 Nonc lusteredIndex),这是从索引表的物理顺序与表中数据行的物理存储顺序是否相同的 角度米分类的。当表中有PRIMARYKEY釣束或WIE钓柬时,SS知Ver会自动在列上建立 索引,至于是素集素引还是非聚集索引由C1.STERED或NONCLUSTERED关键字决定, 1.案集索引 当我门在表格中的某些列上建立聚集素引时,表格中的数据会以度字段作为样序根据 表中数据行的物理存储顺序与索引顺序完全相同。正因如此,一个表格中只能建立一个聚集 索引,但该常引可以包含多个列(组合索》: 当表中保存有连铁值的列时,在这些列上建立聚集素引常有效,因为当使用聚集素引 快速找到一个值时,其它连铁的值白然线在用近。 默认情况下,SQLServer为假IARK迈约束自动建立聚集素引,我们也可在CREATEIND包 语句中用QSTE团域NCLUSTE关键字建立素集或非聚集素引, 聚集素到是指表中数据行的物理存销顺序与素引顺序完全相同。聚集素引由上下两层组 成,上层为素引页,包含表中的索引页面,用于数据检素,下层为数据页。 2非聚集素升 丰聚集引不改变表中数据行的物理存站顺序,数据与泰引分开存储。非聚集索引中仅 包含素引值和指向数据存储位置的指针,索引中的项目按索引健值的顺序存储,而表中的信 息按另一种顺序存储。 S阅Ser在查询数据时,现丰聚集素引进行搜索,找到数据在表中的位置,然后从 根据得到的数据位置信息,到磁盘上的该位置处读取数据。 丰聚集素引中的数据排列顺序并不是表格中的数据排列顺序,这是与聚集素引的主要区 别。因此聚集素引的查海速度比非聚集索引快,非聚集索引又比没有索引快,但是聚集索引 要求数据按理索引顺序在磁盘上排列在一起。 丰豪集需引不改变表中数据行的物理存储位置,数据与需引分开存储,通过需引带有的 指针与表中的数据发生联系。 3隆一素引 根据数据库的功能,可在数据库设计器中创建三种类型的索引一一难一素引、主健素引 和聚集索引。唯一索引不允许两行具有相具的索引值。例如。如果在表中的姓名字段上创建 了唯一索引,则以后用户输入的姓名将不能同名。 聚集索明和非聚集索明都可以是坐一的。因此,只要列中的数据是唯一的,就可以在同
SQLServer 中有两种类型的索引,它们分别是聚集索引(ClusteredIndex)和非聚集索引 (NonclusteredIndex)。这是从索引表的物理顺序与表中数据行的物理存储顺序是否相同的 角度来分类的。当表中有 PRIMARYKEY 约束或 UNIQUE 约束时,SQLServer 会自动在列上建立 索引,至于是聚集索引还是非聚集索引由 CLUSTERED 或 NONCLUSTERED 关键字决定。 1.聚集索引 当我们在表格中的某些列上建立聚集索引时,表格中的数据会以该字段作为排序根据。 表中数据行的物理存储顺序与索引顺序完全相同。正因如此,一个表格中只能建立一个聚集 索引,但该索引可以包含多个列(组合索引)。 当表中保存有连续值的列时,在这些列上建立聚集索引非常有效,因为当使用聚集索引 快速找到一个值时,其它连续的值自然就在附近。 默认情况下,SQLServer为PRIMARYKEY约束自动建立聚集索引,我们也可在CREATEINDEX 语句中用 CLUSTERED 或 NONCLUSTERED 关键字建立聚集或非聚集索引。 聚集索引是指表中数据行的物理存储顺序与索引顺序完全相同。聚集索引由上下两层组 成,上层为索引页,包含表中的索引页面,用于数据检索,下层为数据页。 2.非聚集索引 非聚集索引不改变表中数据行的物理存储顺序,数据与索引分开存储。非聚集索引中仅 包含索引值和指向数据存储位置的指针。索引中的项目按索引键值的顺序存储,而表中的信 息按另一种顺序存储。 SQLServer 在查询数据时,现对非聚集索引进行搜索,找到数据在表中的位置,然后从 根据得到的数据位置信息,到磁盘上的该位置处读取数据。 非聚集索引中的数据排列顺序并不是表格中的数据排列顺序,这是与聚集索引的主要区 别。因此聚集索引的查询速度比非聚集索引快,非聚集索引又比没有索引快,但是聚集索引 要求数据按照索引顺序在磁盘上排列在一起。 非聚集索引不改变表中数据行的物理存储位置,数据与索引分开存储,通过索引带有的 指针与表中的数据发生联系。 3.唯一索引 根据数据库的功能,可在数据库设计器中创建三种类型的索引——唯一索引、主键索引 和聚集索引。唯一索引不允许两行具有相同的索引值。例如,如果在表中的姓名字段上创建 了唯一索引,则以后用户输入的姓名将不能同名。 聚集索引和非聚集索引都可以是唯一的。因此,只要列中的数据是唯一的,就可以在同

一个表上创建一个唯一的聚集索引和多个难一的非聚集素引。贝有当唯一性是数据本身的特 征时,指定唯一索引才有意文。如果必须实该隆一性以确保数据的完整性,则应在列上创建 WTE或吸业xEY约束,面不要创建唯一索引. 创建豫AK了或NIQE约束会在表中指定的列上白动创建难一素引。创建NIQUE 的束与手动创建唯一素引没有明显的区别。进行数据验证的方式相月,而且查询优化器不区 分难一索引是由约束创建还时手动创建。如果存在重复的健值,则无法创建唯一需引和 WTgE钓束。 在同一个列组合上创建唯一素引而不是非唯一索引可为查面优化墨提供附加信息:所以 最好创建唯一索引。 4.2创建索引 42,1使用对象资源管理器创建素引 ()展开指定的服务器和数据岸,选择要创建素引的表,展开该表,选择“索引“,如图 4-34所示,在对象贷源管理器中列出了stud_info表上的已有的需引,包含其需引名称, 是不是聚集素引和是不是唯一索羽。 图4-3别对象资源管理器 (右击需引,从弹出的快捷菜单中透择“新建索引”,就会出现“新建需引”对话框, 在“新建素引”对话框上的“索引名称”文本框中输入所要创建的素引名称,并透释索引类 型(聚集或非紧集),以及是香设置唯一索引, 并在单击“添加”,系统打开如图4-36所示的“从‘stud_info”中选择列”对话框, 在该对话框上选择雷要创建素引的表列。 图4-36“新建索引”对话框 接下来,可以对“素引选项”进行设置。用户只需要选择各复这按钮即可方便的设置各 索引选项。 3打开创建素引对话框的选项页概,在此还可以设定索引的属性,如图37所示。 图4-37索引这项 完成所有的设置工作后,点击“确定”按钮完成索引的创建工作。 4.2.2使用Transact-SgL@创建需引 1.使用T-SL金令创建素引的语法格式 CREATE [UNIQUE][CLUSTERED|NONCLUSTERED]INDEXindex_name ON(tablelview](column[ASCIDESC][....n])
一个表上创建一个唯一的聚集索引和多个唯一的非聚集索引。只有当唯一性是数据本身的特 征时,指定唯一索引才有意义。如果必须实施唯一性以确保数据的完整性,则应在列上创建 UNIQUE 或 PRIMARYKEY 约束,而不要创建唯一索引。 创建 PRIMARYKEY 或 UNIQUE 约束会在表中指定的列上自动创建唯一索引。创建 UNIQUE 约束与手动创建唯一索引没有明显的区别。进行数据验证的方式相同,而且查询优化器不区 分唯一索引是由约束创建还时手动创建。如果存在重复的键值,则无法创建唯一索引和 UNIQUE 约束。 在同一个列组合上创建唯一索引而不是非唯一索引可为查询优化器提供附加信息;所以 最好创建唯一索引。 4.2 创建索引 4.2.1 使用对象资源管理器创建索引 ⑴展开指定的服务器和数据库,选择要创建索引的表,展开该表,选择“索引”,如图 4-34 所示,在对象资源管理器中列出了 stud_info 表上的已有的索引,包含其索引名称、 是不是聚集索引和是不是唯一索引。 图 4-34 对象资源管理器 ⑵右击索引,从弹出的快捷菜单中选择“新建索引”,就会出现“新建索引”对话框, 在“新建索引”对话框上的“索引名称”文本框中输入所要创建的索引名称,并选择索引类 型(聚集或非聚集),以及是否设置唯一索引。 并在单击“添加”,系统打开如图 4-36 所示的“从‘stud_info’中选择列”对话框, 在该对话框上选择需要创建索引的表列。 图 4-36“新建索引”对话框 接下来,可以对“索引选项”进行设置,用户只需要选择各复选按钮即可方便的设置各 索引选项。 ⑶打开创建索引对话框的选项页框,在此还可以设定索引的属性,如图 4-37 所示。 图 4-37 索引选项 完成所有的设置工作后,点击“确定”按钮完成索引的创建工作。 4.2.2 使用 Transact-SQL 创建索引 1.使用 T-SQL 命令创建索引的语法格式 CREATE[UNIQUE][CLUSTERED|NONCLUSTERED]INDEXindex_name ON{table|view}(column[ASC|DESC][,...n])

[VITH[PAD_INDEX] [[]FILLFACTOR=fillfactor] [C.]IGNORE_DUP_KEY] [C,]DROP_EXISTING] [[]STATISTICS_MORECOMPUTE] [[]SORT_IN_TEMPDB] ] [ONfilegroup] 2语法注释 N1E:为表或视图创建唯一素引(不允许存在索引值相同的两行),视图上的聚集索引 必须是WIQE素引, SE:创建一个对象,其中行的物理排序与素引排序相同,并且聚集索引的量低 一级叶级)包含实际的数据行。一个表或程图只允许网时有一个聚集素引。具有聚集索引的 视图称为索程图。必须先为视图创建唯一案集需引,然后才能为该视图定义其它索引。在 创建任阿非聚集索引之前创建聚集素引,创建聚集索引时重建表上现有的幸聚集素引。如果 没有番定CQSE团,则创建非聚集素到。 NONCLUSTERED,创建一个指定表的逻辑排序的对象。对于非聚集素引,行的物理排序魏 立于素引排序。非聚集索引的叶级包含素引行。每个素引行均包含幸聚集健值和一个或多个 行定位器(指向包含该值的行)。如果表没有聚集素引,行定位器就是行的磁盘地址。如果表 有聚集索引,行定位器就是该行的聚集索引健· idex时e:是素引名。素引名在表或视图中必须唯一。们在数据岸中不必唯一。素引 名必须道循标识符线则, t动11包含要创建索引的列的表。可以选择指定数据库和表所有者。 :要建立索引的视图的名称, colu:应用索引的列。指定两个或多个列名,可为指定列的组合值创建组合禽引,在 tb1。后的圆括号中列出组合素引中要包括的列(按排序优先级排列)。 ASC IDE5C:用来指定素引列的排序方式。ASC是升序,E文是降序。 P如五:用来指定索引中阿级中每个页(节点)上保持开放的空间, FI,LFACTOR(填充因子):指定在SQL.Server创建索引的过程中,各素引真叶缓的填满程 度
[WITH[PAD_INDEX] [[,]FILLFACTOR=fillfactor] [[,]IGNORE_DUP_KEY] [[,]DROP_EXISTING] [[,]STATISTICS_NORECOMPUTE] [[,]SORT_IN_TEMPDB] ] [ONfilegroup] 2.语法注释 UNIQUE:为表或视图创建唯一索引(不允许存在索引值相同的两行)。视图上的聚集索引 必须是 UNIQUE 索引。 CLUSTERED:创建一个对象,其中行的物理排序与索引排序相同,并且聚集索引的最低 一级(叶级)包含实际的数据行。一个表或视图只允许同时有一个聚集索引。具有聚集索引的 视图称为索引视图。必须先为视图创建唯一聚集索引,然后才能为该视图定义其它索引。在 创建任何非聚集索引之前创建聚集索引。创建聚集索引时重建表上现有的非聚集索引。如果 没有指定 CLUSTERED,则创建非聚集索引。 NONCLUSTERED:创建一个指定表的逻辑排序的对象。对于非聚集索引,行的物理排序独 立于索引排序。非聚集索引的叶级包含索引行。每个索引行均包含非聚集键值和一个或多个 行定位器(指向包含该值的行)。如果表没有聚集索引,行定位器就是行的磁盘地址。如果表 有聚集索引,行定位器就是该行的聚集索引键。 index_name:是索引名。索引名在表或视图中必须唯一,但在数据库中不必唯一。索引 名必须遵循标识符规则。 table:包含要创建索引的列的表。可以选择指定数据库和表所有者。 view:要建立索引的视图的名称。 column:应用索引的列。指定两个或多个列名,可为指定列的组合值创建组合索引。在 table 后的圆括号中列出组合索引中要包括的列(按排序优先级排列)。 ASC|DESC:用来指定索引列的排序方式,ASC 是升序,DESC 是降序。 PAD_INDEX:用来指定索引中间级中每个页(节点)上保持开放的空间。 FILLFACTOR(填充因子):指定在 SQLServer 创建索引的过程中,各索引页叶级的填满程 度

IGNORE_DUP_KEY:该选项控制当会试向属于嘴一聚集索引的列撬入重复的键值时所发生 的情况。 DP_STI,用来指定应去并重建己角名的先前存在的聚集素引成丰聚集素引。 STATISTICS_NO0OME:月米指定过别的素引绕计不会自动重新计算, S0 RT_IN_TEMPDB:指定用于生成索列的中间排序结果将存储在tc即dh数据库中。 Nf11 eroup:用米在给定的f11 egroup上创建指定的素引。 3简单例子 【练习4.I】在数据库student中的stud_grade表中stud_id列上创建名为 stud_id_index的聚集索引。 USEstudent CO CKEATECLUSTEREDINDEXstud id indexONstud grade (stud id) 0 当用户白表中添PRIMATRYKE'约桌或NIQUE约束时,SQLServer将自动为建有这些约 束的列创建聚集索引,当川户从该表中刷除PIR容约束减WTgE约束时,这些列上创 建的聚集素明也将被白动露。每张数据表上只能存在一个聚集素引: 【练习4.2】在数据库student中的stud_grade表中cours0_1d列上创建名为 Courselndex的非聚集索引。 USEstudent CO CREATENONCLUSTEREDINDEXCourseIndexONstud_grade (course_id) 0 如果没有指定素引类型,SQLServer将使用非聚集索身作为默认的素引类型,当在同一 张表中建立聚集索引和非聚集索引时,应先建立聚集需引后建立非聚集索引。如果先建有非 聚集素引,当建立聚集素引时,S5vr会自动将非聚集索引剩除,然后再重新建立牛聚 集索引: 【练习4,3】在数据库student的stud_grade表stud_1d列上创建名为1 _index的唯 一索引。 USEstudent 00
IGNORE_DUP_KEY:该选项控制当尝试向属于唯一聚集索引的列插入重复的键值时所发生 的情况。 DROP_EXISTING:用来指定应除去并重建已命名的先前存在的聚集索引或非聚集索引。 STATISTICS_NORECOMPUTE:用来指定过期的索引统计不会自动重新计算。 SORT_IN_TEMPDB:指定用于生成索引的中间排序结果将存储在 tempdb 数据库中。 ONfilegroup:用来在给定的 filegroup 上创建指定的索引。 3.简单例子 【练习 4.1】在数据库 student 中的 stud_grade 表中 stud_id 列上创建名为 stud_id_index 的聚集索引。 USEstudent GO CREATECLUSTEREDINDEXstud_id_indexONstud_grade(stud_id) GO 当用户向表中添 PRIMATRYKEY 约束或 UNIQUE 约束时,SQLServer 将自动为建有这些约 束的列创建聚集索引。当用户从该表中删除 PRIMARYKEY 约束或 UNIQUE 约束时,这些列上创 建的聚集索引也将被自动删除。每张数据表上只能存在一个聚集索引。 【练习 4.2】在数据库 student 中的 stud_grade 表中 course_id 列上创建名为 CourseIndex 的非聚集索引。 USEstudent GO CREATENONCLUSTEREDINDEXCourseIndexONstud_grade(course_id) GO 如果没有指定索引类型,SQLServer 将使用非聚集索引作为默认的索引类型,当在同一 张表中建立聚集索引和非聚集索引时,应先建立聚集索引后建立非聚集索引。如果先建有非 聚集索引,当建立聚集索引时,SQLServer 会自动将非聚集索引删除,然后再重新建立非聚 集索引。 【练习 4.3】在数据库 student 的 stud_grade 表 stud_id 列上创建名为 id_index 的唯 一索引。 USEstudent GO

CREATELNIQUEINDEXid_indexONstud_grade(stud_id) 0 【练习44】在数据库student的stud_grade表中course_id列和rade列上创建名 为course_grade_index的复合素引。 USEstudent CO CREATEINDEXcourse_grade_indexONstud_grade (course_id.grade) 0 L设置索达项FILLFACT0派 ()设置FILLFACT0R值时,应考虑如下因素: 填充因子的值是从0到10之间的百分比数值,用来指定在创建素引后对数据页的填充 比例。值为10时表示页将填端,所留出的存储空间量最小。只有当不会对数据进行更改时 (例如在只读表中)才会使月此设置。值越小则数据页上的空闲空间魅大,这样可以诚少在索 引增长过程中对数据页进行拆分的需要,但需要更多的存储空间。当表中数据会发生更改时, 这种授置更为适当: (2)使用s印_c0afiu©系统存储过程可以在服务器级别设置默认的填充因子。 填充因子风在创建索引时扶行:索引创建后,当表中进行数据的添加、别除或更新时, 不会保持填充因子。 【练习4.5】为student数据库中学生成锁表(stud_grade)创建基于学号列的非聚集索 引xh1_1ndex,其填充因子值为0, USEstudent 00 CREATEINDEXxhl indexONstud_crade(stud_id)1THFILLFACTOR=60 0 (F儿FCTO选项用米指定各索明页叶级的琉满程度,对于非叶领索引页者要使用 PD[EX选项设置其顶留空间的大小.PAD INDE贰选项只有在指定了FILLFACTO限时才有用, 因为PAD_INDEX使用由FILLFACTO限所指定的百分比, 如果为FILLFACTOR指定的百分比不够大。无法容纳一行,SS0rveT将在内部使用允 许的最小值餐代该百分比: 【练习46】为student数据库中学生成锁表(stud grade)创建基于学号列的非聚集索
CREATEUNIQUEINDEXid_indexONstud_grade(stud_id) GO 【练习 4.4】在数据库 student 的 stud_grade 表中 course_id 列和 grade 列上创建名 为 course_grade_index 的复合索引。 USEstudent GO CREATEINDEXcourse_grade_indexONstud_grade(course_id,grade) GO 4.设置索引选项 FILLFACTOR ⑴设置 FILLFACTOR 值时,应考虑如下因素: 填充因子的值是从 0 到 100 之间的百分比数值,用来指定在创建索引后对数据页的填充 比例。值为 100 时表示页将填满,所留出的存储空间量最小。只有当不会对数据进行更改时 (例如在只读表中)才会使用此设置。值越小则数据页上的空闲空间越大,这样可以减少在索 引增长过程中对数据页进行拆分的需要,但需要更多的存储空间。当表中数据会发生更改时, 这种设置更为适当。 ⑵使用 sp_configure 系统存储过程可以在服务器级别设置默认的填充因子。 ⑶填充因子只在创建索引时执行;索引创建后,当表中进行数据的添加、删除或更新时, 不会保持填充因子。 【练习 4.5】为 student 数据库中学生成绩表(stud_grade)创建基于学号列的非聚集索 引 xh1_index,其填充因子值为 60。 USEstudent GO CREATEINDEXxh1_indexONstud_grade(stud_id)WITHFILLFACTOR=60 GO ⑷FILLFACTOR 选项用来指定各索引页叶级的填满程度,对于非叶级索引页需要使用 PAD_INDEX选项设置其预留空间的大小。PAD_INDEX选项只有在指定了FILLFACTOR时才有用, 因为 PAD_INDEX 使用由 FILLFACTOR 所指定的百分比。 如果为 FILLFACTOR 指定的百分比不够大,无法容纳一行,SQLServer 将在内部使用允 许的最小值替代该百分比。 【练习 4.6】为 student 数据库中学生成绩表(stud_grade)创建基于学号列的非聚集索