Sql Server 索引以及页和区
索引(Index),相信大家都知道就是给表中的数据添加了一个目录,使我们可以快速检索到我们想要的数据,但这个目录是什么?SqlServer又是如何管理的?要搞明白这些,我们就要先了解sqlserver数据库中的页(Page),区(Extents)的概念,如有不对的地方,欢迎拍砖指正。
页(Page)
-
页是数据存储的最本单位,SqlServer读写也是以页为单位进行的,即页是对数据管理的最小单位。页的大小8192B=8KB, 1MB存储128个数据页。
-
一个页具体如下图所示(图片引用MSDN),包含3部分:
- 头信息Page Hearder,占用96byte,存储关于页的信息,页码,页类型等;
- 数据行DataRows,具体存储的内容,占用8060byte;
- 行偏移表Row Offset Table,记录每个数据行第一个字节和页首(即96byte)的距离,顺序和页中行的顺序相反,占36byte;
-
页的类型本文涉及到的主要如下,其它页类型可自行查询MSDN
- Data:当行中的文本设置为 ON 时,具有除 text、ntext、image、nvarchar(max)、varchar(max)、varbinary(max) 和 xml 数据以外的所有数据的数据行。
- Index:索引条目。
- Text/Image:大型对象数据类型:(text、ntext、image、nvarchar(max)、varchar(max)、varbinary(max) 和 xml 数据),数据行超过 8 KB 时为可变长度数据类型列:(varchar、nvarchar、varbinary 和 sql_variant)
看到上面的Index页类型,我们就明白了索引和数据行一样也是存储在页中的,而且SqlServer针对不同的数据类型划分了不同的页类型,大数据类型(text,image,varchar(max),nvarchar(max))是存储在Text/Image页类型中的,该类型中还会存储单个数据行超过8KB时的可变长类型,即一页中只有一行,且数据行所占空间大小大于8060(即8192-96-36)byte,实际表中所有列的和不能大于8053byte(两者为啥相差7byte可参考此链接),这种情况下sqlServer会从最大长度的可变长度列开始动态将一个或多个列移动到 ROW_OVERFLOW_DATA 分配单元中的页,并在原始页中维护一个指针,如果后续数据行变小,SqlServer会将列再移回来。
区(Extents)
区是磁盘上连续的8个页,8*8KB=64KB。
- 混合盘区 Mixed Extents:每个页可能对应不同对象;
- 统一盘区 Uniform Extents:一个区中的8个页对应一个对象
索引(Index)
通过上面我们已经知道,索引也是存储在页上的,具有聚集索引(Clustered Index)的表是以B-tree(不是B减树。。。)结构组织的且数据按聚集索引顺序存储,否则存储在堆(Heap)上。B树上每一页称为一个索引节点,其中包含:
-
根节点:顶端节点,包含存有索引行的索引页;
-
中间级:根和叶节点之间的,同根节点包含存有索引行的索引页;
-
叶节点:底层节点,包含基础表的数据页;
索引行:包含一个键值和一个指针,该指针指向B树上的某一中间级页或叶级索引中的某个数据行。每级索引中的页均被链接在双向链接列表中.
非聚集索引(Nonclustered Index):具有和聚集索引相同的B树,区别如下:
-
数据行不会按照非聚集键排序和存储;
-
叶级节点指向的不是数据页而是索引页;
索引行:包含非聚集键和行定位符,此定位符指向聚集索引或堆中包含该键值的数据行.
表组织结构图(图片引用MSDN),最底下一行是三种分配单元,详细可直接前往MSDN连接查看。
一些思考:
通过以上内容,我们可以更直观,更容易总结出:
- 应该尽量把索引设置在较窄的列上,这样一个页上就可以存储更多的索引行,检索的效率就高了;
- 经常变动的列上不宜设置索引,因为会导致数据行及索引页的一连串修改调整;
- 建立多个索引可以提供表的查询性能,但同时也增加了修改数据的复杂度;
- 索引应尽量覆盖查询,因为数据全部存储在索引中,从而减少了磁盘I/O
...
最近花了一些时间整理了一下页,区,索引的相关知识点,并看了一些博客,感觉之前很多不懂的地方都豁然开朗了,其实相关内容还有很多 ,这里只是介绍了一部分,另外我们还是要多看官方文档(MSDN建议看英文的,中文翻译的好多地方让你很迷惑,看英文版反而能看懂)和大牛们的博客。
参考链接
文中如有不对之处,欢迎指正。 | ||
本文版权归作者和博客园共有,欢迎转载,但请在文章页面明显位置给出原文连接。 | ||
作者:Nuss | ||
出处:http://www.cnblogs.com/Nuss/ |