其次SQL Server还提供了一个更为友好的命令以找到各个类型的页面分布和它们的所在的文件号和页号。
DBCC IND({'dbname'|dbid},{'objectname'|objectID},
{nonclustered indid|1|0|-1|-2}[,partition_number])
{'dbname'|dbid}表示数据库名或者数据库ID
{'objectname'|objectID}表示对象名或者对象ID
{nonclustered indid|1|0|-1|-2}表示显示行内数据分页及指定对象的行内IAM分页信息
1 :显示所有分页的信息,包括IAM分页,数据分页,所有存在的LOB分页和行溢出页,索引分页
-1: 显示所有IAM、数据分页、及指定对象上全部索引的索引分页.
-2: 显示指定对象的所有IAM分页
nonclustered indid:显示所有的IAM、数据分页以及一个索引的索引分页信息。
{partition_number}->可选,为了与中的DBCC IND命令向前兼容.它指定了一个特定分区号,如果不指定,显示所有分区的信息。
以下是DBCC IND命令输出结果的字段描述:
字段名称 | 字段描述 |
PageFID | 索引文件的ID |
PageFID | 索引文件的ID |
IAMFID | 管理该分页的IAM分页所在的文件ID |
IAMFID | 管理该分页的IAM分页的ID |
ObjectID | 对象ID |
IndexID | 索引ID,0 代表堆, 1 代表聚集索引, 2-250 代表非聚集索引 |
PartitionNumber | 表或索引所在的分区号码 |
PartitionID | 包含该分页的分区ID |
iam_chain_type | 该页所属分配单元类型;行内数据、行溢出数据或Lob数据 |
PageType | 分页类型:1数据页面;2索引页面;3Lob_mixed_page;4Lob_tree_page;10IAM页面 |
IndexLevel | 索引层级,0 代表叶级别分页 ;>0 代表非叶级别层次; NULL 代表IAM分页 |
NextPageFID | 本层下一个分页所在的文件ID |
NextPageFID | 本层下一个分页ID |
PrevPageFID | 本层上一个分页所在的文件ID |
PrevPageFID | 本层上一个分页ID |
继续为了简化的目的,同时因为模拟的是小型数据表,所以可以忽略相关文件号和iam链类型、分区号(该表暂无行内迁移和lob字段),我们只需要看看各 个数据页之间是否有相互联系、各个页面的类型即可;所以我们构建了一张数据表用以存放dbcc ind命令输出的结果,并有选择性的选择我们想要的字段。
CREATE TABLE tablepage
(
PageFID TINYINT,
PagePID INT,
IAMFID TINYINT,
IAMPID INT,
ObjectID INT,
IndexID TINYINT,
PartitionNumber TINYINT,
PartitionID BIGINT,
iam_chain_type VARCHAR(30),
PageType TINYINT,
IndexLevel TINYINT,
NextPageFID TINYINT,
NextPagePID INT,
PrevPageFID TINYINT,
PrevPagePID INT
);
GO
TRUNCATE TABLE tablepage;
INSERT INTO tablepage EXEC ('DBCC IND(testdb,testheap,1)');
SELECT
PagePID,IAMPID,ObjectID,IndexID,Pagetype,IndexLevel,
NextPagePID,PrevPagePID
FROM tablepage
最终结果如下:
我们可以看到SQL Server为该表所使用的页面地址,索引ID、页面类型、索引级别、前后页的关系等等。
Pagetype=10为IAM页面,Pagetype=1为数据页面,即17个数据页面,1个IAM页面,与 system_internals_allocation_units输出结果一致,每一个数据页面都对应该IAM页面地址,indexid=0表示为堆 表,indexlevel=null表示为IAM页面,indexlevel=0表示为叶子节点;而让我们感到有些失望的是每一个页面似乎除了有共同的 IAM管理页面之外,相互之间是缺乏联系的。