• 索引以及页和区


    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
    页的类型本文涉及到的主要如下,其它页类型可自行查询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建议看英文的,中文翻译的好多地方让你很迷惑,看英文版反而能看懂)和大牛们的博客。

    https://www.cnblogs.com/Nuss/p/8642036.html
    参考链接
    MSDN : https://docs.microsoft.com/zh-cn/sql/relational-databases/pages-and-extents-architecture-guide
    http://www.cnblogs.com/woodytu/p/4486193.html

  • 相关阅读:
    Linux下Tomcat服务器-maven项目部署
    数据库设计感悟
    数据库设计规范
    从零到一: 代码调试
    Java泛型与反射的综合应用
    Eclipse中,tomcat插件方式启动项目
    集合查询表--Map
    集合线性表--List之LinkedList(队列与栈)
    集合线性表--List之ArrayList
    Java中的日期操作
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/8660723.html
Copyright © 2020-2023  润新知