
堆數據表是沒有聚集索引的表。即數據行不按任何特殊的順序存儲,數據頁也沒有任何特殊的順序。數據頁不在鏈接列表內鏈接。 sys.system_internals_allocation_units 系統視圖中的列 first_iam_page 指向管理特定分區中堆的分配空間的一系列 IAM 頁的第一頁。SQL Server 使用 IAM 頁在堆中移動。堆內的數據頁和行沒有任何特定的順序,也不鏈接在一起。數據頁之間唯一的邏輯連接是記錄在 IAM 頁內的信息。
那么堆表是如何存儲數據的呢?出于簡化的目的,我們先來構造不含任何索引的一張堆數據表,然后從簡單到復雜逐步深入探討。
--創建一張數據表,從系統表生成測試數據
DROP TABLE testheap
--創建一張2個固定長度字段,3個不定長字段的表,其中4個不為空,1個可為空
CREATE TABLE testheap
(
ID INT IDENTITY(1,1) NOT NULL,
name VARCHAR(20) NOT NULL,
type CHAR(100) NOT NULL,
other VARCHAR(50) NOT NULL,
describle VARCHAR(500)
)
--產生1000條隨機數據,并插入表中
DECLARE @i INT
SET @i=1
WHILE @i<=1000
BEGIN
INSERT INTO testheap(name,type,other,describle)
VALUES('name'+CAST(@i AS VARCHAR(3)),REPLICATE(@i%4,100),FLOOR(RAND()*10),NULL)
SET @i=@i+1
END
SELECT * FROM testheap
--查詢該表的IAM頁面地址和首頁地址
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 ('testheap')))
查詢結果如下:
total_pages | used_pages | data_pages | first_page_address | root_address | IAM_address |
25 | 18 | 17 | 1:224 | 0:0 | 1:119 |
即SQL Server為該表分配了總計25個頁面,實際使用了18個頁面,扣除1個IAM管理頁面,實際數據頁面為17個,IAM管理頁面地址為第一個文件的第119頁面,數據頁面的第一個頁面為第一個文件的第224頁面。
那么如何查看到該表的頁面詳細分配情況呢?
首先通過dbcc page(testdb,1,119,3)可以粗略看到頁面分配情況
即SQL Server首先分配了8個混合區頁面,其次因為該對象已經超過8頁,SQL Server又分配了從第472頁到第487頁的頁面,共計16個頁面,然后包括本身的IAM頁面,共計25個頁面。