SQL Server 2008存储结构之IAM结构

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:

索引分配映射(Index Allocation Map,IAM)页面在4 GB的区间中跟踪被一个分配单元所使用的区。一个分配单元就是一组页面,这些页面属于一个数据表或索引的单个分区。它由下面三种类型页面中的一种组成:含 有常规的行内数据的页面、含有大型对象(Large Object,LOB)数据的页面和含有行溢出数据的页面。 其实SQL Server的数据页面类型与Oracle的段的概念有些类似,一个对象包含若干段,而一个段只能属于一个对象。

  假如一张在四个分区上 的含有所有三种类型的数据(行内数据、LOB数据和行溢出数据)的表将会有至少12个IAM页面。单张IAM页面也是仅仅覆盖单个文件的4GB区间,所以 如果分区跨越多个文件,那么就会有多个IAM页面,同时如果文件大小超过4GB,并且分区使用了一个4 GB区间以外的数据页,那么也将会有额外的IAM数据页。

  一个IAM数据页包含一个页头(IAM页头),该页头包含有8个页面指针槽, 还有一组比特位用来将一个范围内的区映射到一个文件,这个文件并不必一定就是IAM页面所在的那个文件。页头包含有在IAM映射范围内的第一个区的地址。 8个页面指针槽可能包含指向某些属于相关对象页面的指针,这些对象被包含在混合类型的区中,对一个对象来说,只有第一个IAM页面含有这些指针的值。一旦 一个对象占用的页面超过8个,它所有的区都会是统一类型的区——这意味着一个对象决不会需要超过8个指针来指向处于混合类型区中的页面。如果一张表中的数 据行已被删除,该表实际上可以使用的指针数不到8个。比特位映射中的每一个比特位代表了该范围内的一个区,而不论该区是否被分配给了拥有该IAM的对象。 如果一个比特位是打开的,那么在此范围内相关的区就是被分配给拥有 IAM的对象的;如果一个比特位是关闭的,那么此范围内相关的区没有被分配给拥有该IAM的对象。

  IAM页面在需要的时候被分配给每一个对象,并且位于数据库中的随机位置。每一个IAM页面覆盖的可能范围大约是512 000个页面。

  看概念总归是比较枯燥的,我们可以构建一个具体的例子。

  在构建例子之前我们首先需要创建一个把地址转换为具体页码的函数。

CREATE FUNCTION [dbo].f_get_page(@page_num BINARY(6))
RETURNS VARCHAR(11)
AS
BEGIN
RETURN(CONVERT(VARCHAR(2),(CONVERT(INT,SUBSTRING(@page_num,6,1))*POWER(2,8))+
        (CONVERT(INT,SUBSTRING(@page_num,5,1))))+':'+
        CONVERT(VARCHAR(11),
        (CONVERT(INT,SUBSTRING(@page_num,4,1))*POWER(2,24))+
        (CONVERT(INT,SUBSTRING(@page_num,3,1))*POWER(2,16))+
        (CONVERT(INT,SUBSTRING(@page_num,2,1))*POWER(2,8))+
        (CONVERT(INT,SUBSTRING(@page_num,1,1)))))
END
--根据master.sys.objects构建一张叫testIAM的数据表
SELECT * INTO testIAM FROM master.sys.objects    
--然后我们根据之前所知晓的信息,获取testIAM对象的IAM地址,并根据f_get_page函数将地址转换为相应的页面
SELECT total_pages,used_pages,data_pages,
       first_page,root_page,first_iam_page,
       testdb.dbo.f_get_page(first_page) first_page_address,
       testdb.dbo.f_get_page(root_page) root_address,
       testdb.dbo.f_get_page(first_iam_page) IAM_address
  FROM sys.system_internals_allocation_units
WHERE container_id IN (SELECT partition_id FROM sys.partitions
                         WHERE object_id in (SELECT object_id  FROM sys.objects
                                              WHERE name IN ('testIAM')))

dbcc page(testdb,1,80,3)

1

  从dbcc page(testdb,1,80,3)可以得到以下信息

1
 

    因为master.sys.objects的对象只有49条数据,所以只分配了2个页面,根据前文所述,分配8个页面(包括8)以内的对象,SQL Server将以把该对象的数据分配到混合类型的分区上,如上SQL Server给予testIAM表只分配了第一个文件的第77和第89个页面,而并没有分配同一类型的分区的页面。  

  假如我们master.sys.objects的数据反复插入testIAM表,让我们观察一下相应的页面分配情况。

declare @maxtime int
set @maxtime=0
while @maxtime<20
begin
insert into testiam select * from sys.objects
set @maxtime=@maxtime+1
end
select * from testiam
--我们首先还是运行以下system_internals_allcation_units系统表
SELECT total_pages,used_pages,data_pages,
       first_page,root_page,first_iam_page,
       testdb.dbo.f_get_page(first_page) first_page_address,
       testdb.dbo.f_get_page(root_page) root_address,
       testdb.dbo.f_get_page(first_iam_page) IAM_address
  FROM sys.system_internals_allocation_units
WHERE container_id IN (SELECT partition_id FROM sys.partitions
                         WHERE object_id in (SELECT object_id  FROM sys.objects
                                              WHERE name IN ('testIAM')))

--通过上面的结果,我们可以观察到这次SQL Server共分配了17个页面,其中使用了15个页面,而数据页面只有14个,这是为什么呢?
--接着我们再次运行dbcc page命令
dbcc page(testdb,1,80,3)2
   结果如下

2
 

   从上述我们可知,slot 0到slot 7一共分配了8个混合类型区的页面,由于已经超过8页,所以SQL Server再次分配空间时,就会把同一类型的区分配给该对象,一个区包括8个页面,所以SQL Server为testIAM表共分配了16个页面,数据页面14个,已使用的页面除了数据页面还包括该表的一个IAM管理页面。

  还是通过Internals Viewer插件让我们看一下IAM页的情况吧

2
 

  比较有意思的是SQL Server 2008为什么不从一开始就为每一个对象分配同一类型的页面,仅仅是为了节约空间?还是为了与之前版本的兼容性?就不得而知了。

 







本文转自baoqiangwang51CTO博客,原文链接:http://blog.51cto.com/baoqiangwang/413919,如需转载请自行联系原作者

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
4天前
|
SQL API 流计算
实时计算 Flink版产品使用合集之在Mac M1下的Docker环境中开启SQL Server代理的操作步骤是什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
19 1
|
4天前
|
SQL 数据处理 API
实时计算 Flink版产品使用合集之遇到SQL Server锁表问题如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
10 0
|
5天前
|
SQL 关系型数据库 MySQL
实时计算 Flink版产品使用合集之当 SQL Server 源数据库中的数据更新后,CDC 吐出的操作(op)是怎样的
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
15 0
|
6天前
|
SQL XML Linux
SQL Server的版本
【5月更文挑战第14天】SQL Server的版本
21 3
|
6天前
|
SQL 关系型数据库 数据管理
Microsoft SQL Server 是微软公司开发的一款关系型数据库管理系统
【5月更文挑战第14天】Microsoft SQL Server 是微软公司开发的一款关系型数据库管理系统
16 2
|
6天前
|
SQL 存储 数据库连接
LabVIEW与SQL Server 2919 Express通讯
LabVIEW与SQL Server 2919 Express通讯
|
6天前
|
SQL Windows
安装SQL Server 2005时出现对性能监视器计数器注册表值执行系统配置检查失败的解决办法...
安装SQL Server 2005时出现对性能监视器计数器注册表值执行系统配置检查失败的解决办法...
14 4
|
6天前
|
SQL 数据可视化 Oracle
这篇文章教会你:从 SQL Server 移植到 DM(上)
这篇文章教会你:从 SQL Server 移植到 DM(上)
|
6天前
|
SQL 关系型数据库 数据库
SQL Server语法基础:入门到精通
SQL Server语法基础:入门到精通
SQL Server语法基础:入门到精通
|
6天前
|
SQL 存储 网络协议
SQL Server详细使用教程
SQL Server详细使用教程
33 2