浏览 4361 次
锁定老帖子 主题:SQL Server 中索引底层实现
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-09-28
最后修改:2009-09-28
页和盘区(Page and Extents)
你的表(Tables)中数据实际上都存储在页(pages)里,除了BLOB类型的数据。如果某列的字段的类型为BLOB那么将有一个16字节的指针指向BLOB page。页是MS SQL Server中数据存储的最小单位。每页包含以行(row)为单位保存数据。一行只能存储在一个页中。每页可以容纳8KB的信息。因为这个原因,每行的最大值为8KB。一组相邻的8个页被称为一个盘区(Extent) 堆文件和分配映射索引(Heap and the Index Allocation Map(IAM)) 堆文件在sysindexs表中只有一行记录,并且其indid = 0. sysindexs.FIRSTIAM字段指向了IAM页链表中一个IAM页,IAM页是用来管理SQL Server已经给堆文件分配的空间。MS SQL Server2000用IAM(Index Allocation Map)页来在堆文件中导航(navigate)。在堆文件中,数据页(data page)和数据页中数据没有按照特定的顺序存储,也没有链接在一起。数据页之间唯一的逻辑链接是通过IAM页中记录来实现的。 索引结构(Index Structure) 所有的SQL Server 索引都是 B-Trees。在这种树的顶端有一个根页(root page),通过root page来访问N个中级(intermediate level)页,直到树的底部、或叶级(leaf level)。可以通过树中每个节点的指针从上向下扫描整个索引树。另外,每个索引级(index leves)(可能是intermediate leve or leaf level)都有一个页链(page chain)。在一个索引中有许多intermediate level。索引树的级数(树的高度)与索引码的宽度、索引类型、记录行数和表中的页数有关,并且索引树的级数是影响索引性能的一个重要参数。 非聚集索引(Nonclustered Indexs) 一个非聚集索引与一本书的索引相似。数据存储在一个地方,索引存储在另外一个地方,可以通过索引中的指针来访问存储的数据。索引中的条目是按照索引码的值按序存储,但是表中的信息可以按照不同的顺序存储(如可以按照聚集索引存储)。如果表中没有创建聚集索引,那么表中的记录就不能保证按照某种特定的顺序。 与你用一本书的索引方式一样,SQL Server2000也是先通过非聚集索引检索到查找数据在表的位置,然后通过该位置来检索数据。这使得非聚集索引非常适合精确匹配查询(This makes nonclustered indexes the optimal choice for exact match queries),因为索引条目中包含了你需要查找数据的位置信息。如果当前的表是以聚集索引方式存储,那么非聚集索引的位置信息就是聚集索引的索引码(index key);否则,位置信息就是row ID(RID),每个RID由file number、page number和 slot number of row(每行记录的槽号)。比如,要在一个表中检索某个employee ID(emp_id),该表已经有在emp_id列上创建了非聚集索引,SQL Server查找索引树,找到一个索引条目包含你需要查找的emp_id,然后利用其中RID来访问到对应数据页中的值。 注意事项 非聚集索引适用于以下场景:
聚集索引(Clustered Indexs) 一个聚集索引决定了一个表中数据的物理存储顺序。一个聚集索引与一个电话目录相似,电话目录是按照last name来存放。因为聚集索引决定一张表中数据的物理存放顺序,所以一张表只能有个聚集索引,一个聚集索引可以包含多个列(复合索引),就像电话目录一样按照last name 和 first name记录一样,聚集索引与Oracle中的IOT'S(Index-Organized Tables)相似。 一个聚集索引对范围查询非常有效率efficient on columns that are often searched for ranges of values。当用聚集索引把第一个行检索出来之后,后续行一定能保证在物理上是相邻的。例如,应用的某个查询需要频繁执行一个范围查询,聚集索引可以快速定位到满足条件的第一个数据,然后再检索表中与之相邻的记录直到最后一条记录。这样可以调高这类查询的性能。另外,如果某列经常用来对表中的数据进行排序(sort),该情况下也可利用聚集索引来节省每次排序的时间。 当索引值唯一时,需要查找一个指定行,此时聚集索引也是高效率的。例如,用最快的方式来找到一个指定empoyee ID的employee记录就是在emp_id列上创建一个聚集索引。 注意事项 在创建聚集索引时,索引列应该尽量少,这一点很重要。如果定义一个大的索引码,那么该表中的任何非聚集索引就会显著的增大,因为每个非聚集索引叶级索引条目都包含了一个聚集索引码。 聚集索引适用于以下场景:
聚集索引不适合以下场景:
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |