SQL Server索引类型和索引导航

来源:互联网 发布:linux搜索所有文件 编辑:程序博客网 时间:2024/05/29 15:10

虽然在SQL Server中名义上有两种类型的索引(聚集索引和非聚集索引),但实际上,内部来说有3种索引类型,分别是 聚集索引,非聚集索引其中包含堆上的非聚集所以,聚集索引上的非聚集索引。

物理数据的存储方式在聚集索引和非聚集索引之间有所不同。SQL Server遍历B树到达最终数据的方式在3种索引类型之间各不相同。

所有SQL Server索引都有叶级页和非叶级页。叶级页和非叶级页。叶级是保存标识记录的“键”的,非叶级是引到到叶级的。

索引要么构建在聚集表(有聚集索引的表)上,要么构建在堆(没有聚集索引的表)上。

提示:你可能会产生这样的疑问,“如果聚集索引不是唯一的,将会怎样呢?”既是说,如果聚集索引不是唯一索引,怎样才能用聚集索引唯一标识一行呢?答案是隐蔽的:SQL Server强制所有的聚集索引唯一,即使没有把聚集索引定义成唯一的,也是如此。幸运的是,它强制索引唯一的方式不会改变索引的使用方式。如果你愿意,仍然可以插入重复的行,只是SQL Server 会在内部为键添加后缀,以确保该行具有唯一的标识符。

堆是任何没有聚集索引的表。这种情况下,将基于该行的区段、页和行偏移量(从页首到该行的距离)的组合来创建唯一标识符或行ID。只有当没有聚集键可用时(没有聚集索引),RID才是必须的。

1聚集索引

对任何指定的表来说,聚集索引是唯一的——每个表只能有一个聚集索引。并非一定要有聚集索引。但是,你会发现它是最经常作为第一个索引选用的索引类型,由于各种各样的原因,查看索引类的时候,那会是非常明显的。

聚集索引的特殊之处在于,它的叶级是真正的数据——即数据按照索引或相关键命令中定义的物理顺序进行排序存储。这意味着,一旦到达索引的叶级,就到达了终点——这里是真正的数据。新纪录根据它在聚集索引里正确的物理顺序进行插入。创建新页的方式会随着需要插入记录的位置的变化而变化。

当新纪录必须插入到索引结构中间时,会发生常规的页拆分。来自原来页中后半部分的记录被移动到新页上,新纪录适当地插入到新的或旧的页中。

当新纪录在逻辑上位于索引结构的末尾时,将创建一个新页。但是只有新纪录添加到新页中,如图所示。

在数中导航

SQL Server中的索引以B树结构存储。在理论上,在B树分叉的每一个方向上,总是有一半的剩余信息。下面来看一下聚集索引的B树图示


可以看出,它实际上与一般的B树是一样的。在这里进行的是范围搜索(有时聚集索引尤其擅长此类事情)。搜索158—400的数字,只需要按照如下步骤进行:导航到第一条记录,并包含该页中所有的其余记录(之所以知道需要该页中其余的记录,是因为我们从上一级节点的信息中得到还需要来自其它页中的数据。因为这是一个有序的列表,所哟可以确定它是连续的),这意味着如果下一页中有需要包含进来的记录,那么本页中其余的记录必定都要包含进来。我们可以开始从这些页中提取记录,而不需要完成确认方面的工作。我们从导航节点开始。SQL Server可以基于一个保存为系统表的条目定位跟节点。可以通过查询sys.indexes查看那个表的逻辑内容。

注意:数据库中的每一个索引在sys.indexes中都有一个条目。系统视图是数据库的一部分(与主数据库中相反)而且会显示数据库中所有索引的存储位置信息,以及它们基于那个列。在版本较旧的SQL Server中。可以查询基础表(在技术上你可以这么做,不过本人强烈推荐你不要直接查询),即所谓的sysindexes表。

浏览作为根节点的页,可以知道接下来要检查的页是什么(正如图中所显示,我们要查看第二级的第二页)。然后,继续处理。随着我们沿着树一步步向下,将得到越来越小的数据子集。最终,我们会到达索引级别的叶级。在聚集索引中,到达索引的叶级意味这也到达了要找寻的行和要找寻的数据。

注意:关于区别重要性,我已经强调过很多了。有了聚集索引,在完整浏览索引的时候就已经完整地浏览了自己的数据。早你观察非聚集索引的时候会发现这样做对性能的影响差别有多大——特别是在聚集索引上建立非聚集索引的时候。

2堆上的非聚集索引

堆上的非聚集索引在各方面都与聚集索引的作用方式很类似。不过它们确实有几个显著的区别:叶级不是数据,而是你可以获得数据指针的级别。指针以索引指向的特定行的行标识符(RID)的形式出现,对于RID大家都应该有所了解,它由索引指向特定行的区段、页和行偏移量组成。尽管叶级并非真正的数据(而是具有RID)。不过,这里只比使用聚集索引多了一步而已——因为RID包含行位置的完整信息,因而可以直接访问数据。不过不要误以为“多了一步”意味着在开销上只有一点点差别,进而误以为堆上的非聚集索引与聚集索引运行的一样快。使用聚集索引时,数据的物理顺序是索引顺序。这意味着,对于一定的数据范围,当找到该范围上数据起点所在的行时,很可能该页上其它行也和它一起在这一页上(也就说,因为他们存储在一起,所以在物理上你基本上已经到下一条记录了)使用堆的时候,数据没有链接在一起,唯一的连接就是通过索引。从物理的观点看,这里完全没有任何形式的排序。就是说,从物理观点来看,系统可能要在文件中四处检索数据。实际上,十分可能(或者很可能)要花上单独的几次从同一个页中获取数据,因为数据间没有链接,所以SQL Server无法知道它将返回这个物理位置。使用聚集索引时,因为知道物理的顺序,所以可以只访问页一次就获取到所有的数据。

在大多数索引导航中,这里所做的事情与以前完全一样。从同一根节点开始,遍历树处理越来越集中的页,直到达索引级别的叶级、此时,事情开始与有所不同。使用聚集索引时,就到此为止,而使用非聚集索引时,要做更多的事情。如果非聚集索引在堆上,那么还需要到达一个级别。从叶级获取行标识符。然后导航到该行,一直到这是才找到实际的数据、

3聚集表上的非聚集索引

使用聚集表上的非聚集索引时,同样有相似之处。但也 同样有不同之处。与堆上的非聚集索引一样,索引的非叶级看起来和聚集索引非常类似、只要到达叶级才可以看到不同之处。


原创粉丝点击