SQL Server内部如何管理对象的数据Page?
一个表或Index使用的数据页空间是由IAM Page Chain来管理的。SQL Server 使用一个IAM(Index Allocation Map)Page来管理数据库文件中最多4GB的空间,一个IAM Page映射文件中4GB大小中的区(Extent),区由8个物理地址连续的Page构成,是由分配单元(Allocation Unit)负责分配的,分配单元有三种类型:
- IN_ROW_DATA:保存堆(heap)或索引(index)的一个分区(partition)
- LOB_DATA:保存LOB(Large Object)数据类型,LOB数据类型是:xml,、varbinary(max)、varchar(max)和nvarchar(max)
- ROW_OVERFLOW_DATA:保存变长数据(varchar, nvarchar, varbinary, 或 sql_variant )类型,且超过8060Bytes的列。
每一个heap或index都包含至少一个IN_ROW_DATA 分配单元,可能包含 LOB_DATA 或 ROW_OVERFLOW_DATA 分配单元。
一,对大数据行的支持
在SQL Server中,一个数据行不能跨越Page,但是,可以把行的某些部分移除该行所在的页面。一个Page上的单行可以包含的最大数据量和管理开销(Overhead)之和是8060字节。对于包含变长类型(varchar,nvarchar,varbinary或sql_variant)列的表,当一行中的所有固定大小列和变长列的总大小超过8,060字节的限制时,SQL Server将从宽度最大的列开始,把一个或多个可变长度列移动到ROW_OVERFLOW_DATA分配单元中的页面,这样一行数据实际上存储在两个或多个Page上。
只要插入或更新操作把行的总大小增加到超过8,060字节的限制,SQL Server就自动执行此操作,把最大的变长列移动到ROW_OVERFLOW_DATA分配单元中的页面中,只把存在于IN_ROW_DATA分配单元中原始页面上的24字节的指针保留下来,该指针指向ROW_OVERFLOW_DATA 页面。如果后续的更新操作导致该行减少到小于8,060字节,那么SQL Server自动把列移回到原始数据页中。
二,数据表使用的Page
一个表或Index使用的空间是由数据Page和相应的管理Page构成的,其中数据页是由IAM Page Chain来管理的,而IAM Pages也属于对象占用的硬盘空间,是为了管理数据页而必须付出的代价。一个IAM Page映射文件中的4 GB范围,并且与GAM或SGAM页的覆盖范围相同。 如果分配单元(allocation unit)包含来自多个文件或一个文件的大于4GB范围的区(Extent),那么分配单元存在多个IAMP Page,且这些IAM页面连接成一个IAM 链。IAM Page链是双向链,每一个Page中都存在向前和向后的指针,通过这两个指针找到前一个页面和后一个页面。
对于每一个数据库文件,如果分配单元在该文件中存在区(Extent),那么该分配单元在该文件上至少存在一个IAM页。也就是说,每个分配单元在其具有Extent的每个文件中至少拥有一个IAM页。 如果文件上分配给分配单元的扩展区范围超出了单个IAM页可以记录的范围(4GB),则在该文件上也可能有多个IAM页。

IAM Page根据每个分配单元的需要进行分配,IAM Page在文件中的位置是随机的,SQL Server提供一个非正式的内部使用的视图 sys.system_internals_allocation_units,该视图中的first_page字段指向分配单元的第一个IAM页面,可以认为是IAM 链(Chain)的根(Root)页面。由于分配单元的所有IAM页面都链接在一起,通过根页面里的指针,顺着双向链,可以遍历分配单元的所有IAM Page,进而可以查找到表或索引的所有数据页。


对于视图返回的字段 container_id,用于表示跟分配单元相关链的存储容器,表示的是hobt_id 或 partition_id,由type值来确定,匹配的规则如下:
- If type = 1 or 3, container_id = sys.partitions.hobt_id.
- If type is 2, then container_id = sys.partitions.partition_id.
- 0 = Allocation unit marked for deferred drop
SQL Server 还提供了一个正式视图 sys.allocation_units,用于查看分配单元的信息,该视图和sys.partitions关联起来,可以用于查看跟该分配单元相关的分区数据:
select *
from sys.allocation_units u
cross join sys.partitions p
where u.type in (1,3) and u.container_id = p.hobt_id
or u.type=2 and u.container_id= p.partition_id
三,空间的延迟删除
当您删除或重建大型索引,或者删除或truncate大型表时,数据库引擎会推迟实际的page回收,直到事务提交为止。 延迟删除操作不会立即释放被分配的空间,因此,在drop或truncate大对象之后,sys.allocation_units 实时返回的值可能无法正确反映实际的可用磁盘空间。这也是 container_id =0 表示分配单元被标记为延迟删除的原因。
参考文档:
Pages and Extents Architecture Guide
SQL Server内部如何管理对象的数据Page?的更多相关文章
- 清空SQL Server数据库中所有表数据的方法(转)
清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入 ...
- SQL Server跨库复制表数据错误的解决办法
SQL Server跨库复制表数据的解决办法 跨库复制表数据,有很多种方法,最常见的是写程序来批量导入数据了,但是这种方法并不是最优方法,今天就用到了一个很犀利的方法,可以完美在 Sql Serv ...
- 快速查看SQL Server 中各表的数据量以及占用空间大小
快速查看SQL Server 中各表的数据量以及占用空间大小. CREATE TABLE #T (NAME nvarchar(100),ROWS char(20),reserved varchar(1 ...
- 清空SQL Server数据库中所有表数据的方法
原文:清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可 ...
- EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的
我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值. 下面我们通过例子来展示,EF ...
- 将SQL SERVER中查询到的数据导成一个Excel文件
-- ====================================================== T-SQL代码: EXEC master..xp_cmdshell 'bcp 库名. ...
- 也谈SQL Server 2008 处理隐式数据类型转换在运行计划中的增强 (续)
在上一篇文章也谈SQL Server 2008 处理隐式数据类型转换在运行计划中的增强中,我提到了隐式数据类型转换添加对于数据分布非常不平均的表.评估的数据行数与实际值有非常大出入的问题,进一步測试之 ...
- 腾讯云图片鉴黄集成到C# SQL Server 怎么在分页获取数据的同时获取到总记录数 sqlserver 操作数据表语句模板 .NET MVC后台发送post请求 百度api查询多个地址的经纬度的问题 try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会 不会被执行,什么时候被执行,在 return 前还是后? js获取某个日期
腾讯云图片鉴黄集成到C# 官方文档:https://cloud.tencent.com/document/product/641/12422 请求官方API及签名的生成代码如下: public c ...
- 使用Sql Server Management Studio 2008将数据导出到Sql文件中
最近需要将一个Sql Server 2005数据库中的数据导出,为了方便,就希望能导出成Sql文件,里面包含的数据是由Insert 语句组成的. 在Sql Server Management St ...
随机推荐
- JS数组去掉某一个元素
/**数组去掉某一个元素**/ Array.prototype.remove = function(val) { var index = this.indexOf(val); if (index &g ...
- Pairs Forming LCM (LightOJ - 1236)【简单数论】【质因数分解】【算术基本定理】(未完成)
Pairs Forming LCM (LightOJ - 1236)[简单数论][质因数分解][算术基本定理](未完成) 标签: 入门讲座题解 数论 题目描述 Find the result of t ...
- 从荣耀 xSport Pro 运动蓝牙耳机发布看蓝牙立体声耳机的新动态
10月22日,荣耀在北京举行新品发布会,不仅带来了荣耀20青春版手机,还正式发布了荣耀xSport PRO运动蓝牙耳机.该款耳机是荣耀全新一代颈戴式运动蓝牙耳机,兼具运动和时尚属性,高颜值的渐变色机身 ...
- redis的embstr编码
问题来了 今天在看书籍<Redis设计与实现>的时候,在8.2字符串对象里面写到 如果字符串对象保存的是一个字符串值, 并且这个字符串值的长度大于 39 字节, 那么字符串对象将使用一个简 ...
- Git详细学习教程
作者:gafish https://github.com/gafish/gafish.github.com Git简介 Git 是一种分布式版本控制系统,它可以不受网络连接的限制,加上其它众多优点,目 ...
- [javascript string] slice();substr();substring();之间的区别
今天遇到这个问题,发现ぜんぜんわすねまます3个方法,直接上代码吧,[网络版本较多就不注明参考过哪些了 -0- ] var test = 'hello world'; //均一位参数测试 console ...
- SQL 高效运行注意事项(三)
合理配置tempdb 1.tempdb在SQL Server停掉,重启时会自动的drop,re-create. 根据model数据库会默认建立一个新的 2.tempdb对IO的要求比较高,最好分配到高 ...
- RPM常用命令总结
安装 rpm -ivh package_name (package_name指的是RPM包的文件名) 查询 1.查询是否安装,及安装版本 rpm -q 已安装的软件名(ex:rpm -q docker ...
- CQRS(Command and Query Responsibility Segregation)与EventSources实例
CQRS The CQRS pattern and event sourcing are not mere simplistic solutions to the problems associate ...
- 201871010124 王生涛《面向对象程序设计JAVA》第一周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://edu.cnblogs.com/campus/xbsf/ ...