索引配置對應(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)