SQL Server 2008儲存結構之IAM結構
假如一張在四個分割槽上 的含有所有三種型別的資料(行內資料、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個頁面。
看概念總歸是比較枯燥的,我們可以構建一個具體的例子。
在構建例子之前我們首先需要建立一個把地址轉換為具體頁碼的函式。
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)
從dbcc page(testdb,1,80,3)可以得到以下資訊
因為master.sys.objects的物件只有49條資料,所以只分配了2個頁面,根據前文所述,分配8個頁面(包括8)以內的物件,SQL Server將以把該物件的資料分配到混合型別的分割槽上,如上SQL Server給予testIAM表只分配了第一個檔案的第77和第89個頁面,而並沒有分配同一型別的分割槽的頁面。
假如我們master.sys.objects的資料反覆插入testIAM表,讓我們觀察一下相應的頁面分配情況。
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為什麼不從一開始就為每一個物件分配同一型別的頁面,僅僅是為了節約空間?還是為了與之前版本的相容性?就不得而知了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6517/viewspace-677207/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Server 2008儲存結構之PFS結構SQLServer
- SQL Server 2008儲存結構之GAM、SGAMSQLServerGAM
- SQL Server 2008 儲存結構之DCM、BCMSQLServer
- SQL Server2008儲存結構之物件儲存檢視SQLServer物件
- 理解SQL Server 2008索引的儲存結構YDSQLServer索引
- SQL Server2008儲存結構之基本系統檢視SQLServer
- SQL Server2008儲存結構之堆表、行溢位SQLServer
- 儲存結構
- PostgreSQL儲存引擎之page結構SQL儲存引擎
- JanusGraph -- 儲存結構
- CentOS 儲存結構CentOS
- SQL Server 2008的加密層次結構SQLServer加密
- SQL Server 索引結構SQLServer索引
- PostgreSQL儲存引擎之heap tuple結構SQL儲存引擎
- SQL Server2008無法修改表結構?SQLServer
- Redis儲存結構以及儲存格式Redis
- 圖的儲存結構
- 三種儲存結構
- 資料結構知識點--儲存結構與邏輯結構資料結構
- 線性表之順序儲存結構
- 線性表之鏈式儲存結構
- 【資料結構——圖和圖的儲存結構】資料結構
- MySQL InnoDB的儲存結構總結MySql
- InnoDB記錄儲存結構
- php圖的儲存結構PHP
- HBase 資料儲存結構
- redis 儲存結構原理 2Redis
- oracle物理儲存結構理解Oracle
- Oracle資料儲存結構Oracle
- SAP儲存地點結構
- SQL Server 索引結構及其使用SQLServer索引
- 讀取SQL Server 表結構SQLServer
- 【PHP資料結構】圖的概念和儲存結構PHP資料結構
- MySQL Innodb 儲存結構 & 儲存Null值 解析MySqlNull
- 儲存器的層次結構
- 圖(Graph)——圖的儲存結構
- 【RocketMQ】RocketMQ儲存結構設計MQ
- innodb表空間儲存結構