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 ...
随机推荐
- 调试seanbell/intrinsic遇到的坑
那些遗忘过去的人注定要重蹈覆辙.——乔治•桑塔亚纳 Authorized error 刚开始按作者 GitHub 上的指示,当运行环境配置好,并且 make 之后,因为生成的 decompose.p ...
- Quartz.NET总结(三)如配置jobs
前两篇文章,已经介绍了Quartz.NET的使用和Cron表达式表达式的写法,今天说一说Quartz的配置,Quartz相关的配置有三个quartz.config.quartz_jobs.xml.lo ...
- Slickflow.NET 开源工作流引擎快速入门之一: 简单序列流程代码编写示例
前言:对于急切想了解引擎功能的开发人员,在下载版本后,就想尝试编写代码,完成一个流程的开发和测试.本文试图从一个最简单的流程来示例说明,如何快速了解引擎代码的编写. 版本: .NETCore 2.1 ...
- Go-内置time包
一.导入包 import "time" 二.转换成Time对象 获取当前时间:time. Now () 自定义时间:time. Date(year int, month Month ...
- Docker 镜像介绍和命令
目录 是什么 UnionFS(联合文件系统) Docker镜像加载原理 分层的镜像 为什么 Docker 镜像要采用这种分层结构呢 特点 Docker镜像commit操作补充 案例演示 1.从Hub上 ...
- 0day2安全——笔记4(修改临界变量)
第二章 修改临界变量 #include <stdio.h> #include <string.h> #define PASSWORD "1234567" i ...
- IDEA中增加日志相关的Live Templates
1.新增一个Template Group 来将一个类型的放一起 2.在Template Group增加Live Template 这里可以分为三步 第一步填写想要看到的代码,变量部分用$paramet ...
- 201871010123-吴丽丽《面向对象程序设计(Java)》第一周学习总结
201871010123-吴丽丽<面向对象程序设计 ...
- GAN网络原理介绍和代码
GAN网络的整体公式: 公式各参数介绍如下: X是真实地图片,而对应的标签是1. G(Z)是通过给定的噪声Z,生成图片(实际上是通过给定的Z生成一个tensor),对应的标签是0. D是一个二分类网络 ...
- Acwing40. 顺时针打印矩阵
地址 https://www.acwing.com/solution/acwing/content/3623/ 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 样例 输入: [ [, ...