T-SQL执行内幕(8)——数据存储

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DBA_Huangzj/article/details/79758521

本文属于SQL Server T-SQL执行内幕系列


    前面提到了数据访问,那么如何访问?访问什么?为此必须介绍一下数据存储的概念。SQL Server以三种方式存储和组织数据:均可从sys.partitions中查到

  • Heaps:堆,指没有聚集索引(注意主键并非一定是聚集索引)的表。另外诸如select …into … from …语句生成的表也是堆表。SQL Server堆结构

    在sys.partitions中每个堆表有一行对应的值,其中index_id为0。从SQL 2005开始,默认情况下,一个堆表就是一个分区,如果一个堆表有多个分区,那么每个分区都包含一个堆结构。堆表数据没有顺序。或者说,除非明确在语句中使用Order by子句,否则不能保证结果集的顺序。通过扫描IAM页可以进行堆的表扫描或串行读取,串行堆扫描会按顺序扫描每个文件,意味着堆中的行不会按照插入时的顺序返回。

  •  Clustered Index:聚集索引,也叫聚集表,与堆表相对,虽然叫“索引”,但是实际上它是表的另外一种组织方式(B-Tree,B树),也就是说它还是表本身,只是一个表要么是堆表,要么是聚集表,两者不可共存。SQL Server 聚集索引结构

    索引中的页称为一个索引节点。B树顶部的节点为根节点。最底部的节点为叶子节点聚集索引的叶子节点包含了表的实际数据页。根及中间节点包含多个索引行的索引页,每个索引行包含一个键值和指向其他中间结点页的指针或者指向叶子节点的数据行。并且每级节点使用双向列表互相关联。

    聚集索引在sys.partitions中有index_id=1的行一一对应每个分区。默认一个聚集索引就是一个分区。如果有多个分区,每个分区包含一个独立的聚集索引。 

  • Nonclustered Index:非聚集索引,与前面两种不一样的是,堆表和聚集表都可以有非聚集索引,而且通常它并不包含表本身的所有数据。更多的是一个数据表的“子集”,我们在性能优化和数据库设计中常说的索引大部分情况下就是非聚集索引。同样,它也是B-Tree结构。SQL Server非聚集索引结构

    从SQL Server 2012开始,引入了另外一种数据组织结构——列式存储,相对于聚集索引和非聚集索引这种B-Tree结构,2012只有非聚集列式存储(Nonclustered Columnstores),2012之后的版本引入了聚集列式存储(Clustered Columnstore)。更多内容可以参考:http://rusanu.com/2012/05/29/inside-the-sql-server-2012-columnstore-indexes/http://rusanu.com/2013/06/11/sql-server-clustered-columnstore-indexes-at-teched-2013/

术语说明:

    页、区:

    这是数据实际存储的单位,页为8K,区为连续的8个页。8个连续的页会组合成一个区。区不能小于8个页。SQL Server包含混合区和统一区两类区。在混合区中,每个页可以分配给不同的对象,比如当一个表初次创建,并且数据足够存放在少于8个页中时,SQLServer会创建一个混合区来存放这些页。当表的数据越来越多,8个页无法满足存储时,SQL Server会合并混合区成为一个统一区。

    注意:如果一个表增长到8个页以上,那么前8个页还是存在于混合区,从第九个页开始才分配统一区,除非重建表(比如rebuild table)。


    B-Tree

    是一种平衡树数据结构,用于位置数据顺序和允许搜索、顺序访问、插入和删除操作。专为读写大块数据的系统而设计。B树是反过来的一棵树,最顶端只有一个节点,称为根节点,最低端称为叶子节点,中间的各级节点统称中间节点。

    IAM:Index Allocation Map 

    这个页对于索引来说非常重要,SQL Server经常需要知道特定表或者索引上是否有页关联,而这些信息存放在IAM页中。每个表或者索引都从IAM页开始,并标识存放在GAM的哪个区,如果一个表或者索引跨了多个GAM,就会有多个IAM页关联。IAM页有4类页面关联,数据页、索引页、LOB对象和small-large对象页。它们在IAM的bit中体现。

 对于页的研究,强烈推荐一个很好的工具:InternalsViewer for SQL Server,下载地址:http://internalsviewer.codeplex.com/这是一个图形化的工具,可以通过图形化的界面来粗略了解区、页的情况,对于入门级别的读者来说相当有效。不过比较遗憾的是目前只支持到2008。

总结

    数据存储组成了数据库的“空间”概念,空间的大小最精确的统计就是统计页的数量,当然如果你要走极端,统计行的bytes数更加准确。数据类型、行数、列数又影响了页的大小,碎片情况又影响了区的大小。

    空间问题,又从根本上制约了性能,所以在设计和编程过程中,多考虑数据类型的使用非常重要。

    更多详细信息可以参考本人书籍《SQL Server性能优化与管理的艺术》一书第六章。

猜你喜欢

转载自blog.csdn.net/DBA_Huangzj/article/details/79758521