假如我们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)
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)
结果如下
从上述我们可知,slot 0到slot 7一共分配了8个混合类型区的页面,由于已经超过8页,所以SQL Server再次分配空间时,就会把同一类型的区分配给该对象,一个区包括8个页面,所以SQL Server为testIAM表共分配了16个页面,数据页面14个,已使用的页面除了数据页面还包括该表的一个IAM管理页面。
还是通过Internals Viewer插件让我们看一下IAM页的情况吧
比较有意思的是SQL Server 2008为什么不从一开始就为每一个对象分配同一类型的页面,仅仅是为了节约空间?还是为了与之前版本的兼容性?就不得而知了。