索引初探(二)
在SqlServer中分为两种索引,一是聚集索引;一是费聚集索引。下面我就分别对两种索引进行介绍并分析其区别和各自的特点。
1.聚集索引
之前看过一个比方,我觉得非常恰当这里也用这个例子来说明两种索引。我们的字典本身就像是一个聚集索引,我们根据拼音查找目录,然后直接可以找到查询字的页,而字典正文就是按照拼音的顺序进行的排序。从中我们不难总结聚集索引的特点:
- 物理排序与逻辑排序顺序一致。
- 每个表的此种排序只有一种。
如图:
- 表中的全部数据都保存在B树中的叶层(leaf level)中,其他层只是起到一个索引的作用,并不包含任何数据。叶层是一个双向链表结构,并按照聚集索引的主键的逻辑顺序排列。因此逻辑顺序是用指针来维护。
- 举例说明建立聚集索引的效果:
- 上图没有建立聚焦索引的表根据时间段进行查询,结果逻辑读取了4080次,而同样对该时间段进行查询,建立索引后,逻辑读取锐减至1792次。可见聚集索引能大大减少io消耗,对于大规模数据的读取的性能提升是显而易见的。同时我们在对比数据的排序
- 如图所示,在添加聚集索引前,数据以堆的形式按照先后顺序排列,增加聚集索引后,按照索引字段进行了逻辑排序。
接下来我们简单讨论一下:
1)聚集索引与插入操作
最简单的情况下,插入操作根据索引找到对应的数据页,然后通过挪动已有的记录为新数据腾出空间,最后插入数据。
如果数据页已满,则需要拆分数据页(页拆分是一种耗费资源的操作,一般数据库系统中会有相应的机制要尽量减少页拆分的次数,通常是通过为每页预留空间来实现):
在该使用的数据段(extent)上分配新的数据页,如果数据段已满,则需要分配新段。
调整索引指针,这需要将相应的索引页读入内存并加锁。
大约有一半的数据行被归入新的数据页中。
2)聚集索引与删除操作
删除行将导致其下方的数据行向上移动以填充删除记录造成的空白。
如果删除的行是该数据页中的最后一行,那么该数据页将被回收,相应的索引页中的记录将被删除。如果回收的数据页位于跟该表的其它数据页相同的段上,那么它可能在随后的时间内被利用。如果该数据页是该段的唯一一个数据页,则该段也被回收。
对于数据的删除操作,可能导致索引页中仅有一条记录,这时,该记录可能会被移至邻近的索引页中,原索引页将被回收,即所谓的“索引合并”。
- 2.非聚集索引
- 非聚集索引也是以B树组织的。和聚集索引的区别就在于它的叶层并不包含所有的数据。在默认情况下它只包含了键列的数据,并包含了一个行定位符(row locator)。这个行定位符的具体内容取决于它建立在以堆形式的表还是以B树组织的表,换句话说也就是这张表是否建立了聚集索引会影响到非聚集索引的行定位符。如果是建立了聚集索引,那么这个行定位符就是一个聚集键,我们通过这个聚集键再次查找聚集索引上的数据。
- 如图:
- 总结
- 这我们基本了解了聚集索引和非聚集索引,不难看出聚集索引是提高查询性能的利器。索引有助于提高检索性能,但过多或不当的索引也会导致系统低效。因为用户在表中每加进一个索引,数据库就要做更多的工作。过多的索引甚至会导致索引碎片。 比如当插入索引是就会引发一些列的操作从而影响系统性能,当然鱼和熊掌不能兼得,还得根据实际情况客观分析来建立合适的索引体系。下一节将专门展开介绍非聚焦索引。(写的太随笔,周末有事也是简单先写一点,不好意思了)