一、使用以下语句获取分区及分配信息
partition_number as pnum, rows, allocation_unit_id as au_id,
type_desc as page_type_desc, total_pages as pages
from sys.partitions p join sys.allocation_units a
on p.partition_id = a.container_id
where object_id = object_id ( ' 表名 ' )
结果如下:
二、使用语句
where allocation_unit_id = 分配单元Id
分配单元Id就是图1中pages值最大的au_id值。
得到的first_page是一个16进制数字,需要转换成文件号和页号,转换规则:
在first_page中,每两个16进制数字表示一个字节,并且是逆序排列的。比如值为0xC70000000100,怎么转换呢?因为它是逆序排列的,并且每两个表示一个字节,所以每次都将剩下 first_page值的最后两位移到转换后数据的最后:
步骤 此时的first_page值 转换后的数据
第0步 0xC70000000100
第1步 0xC700000001 00
第2步 0xC7000000 0001
第3步 0xC70000 000100
第4步 0xC700 00010000
第5步 0xC7 0001000000
第6步 0x 0001000000C7
此时转换完成。数据0001000000C7即是我们需要的数据,其中它的前2组数(即0001)表示该表所在的文件编号;后4组(000000C7)表示该表所在的页码(注意该数据还要转换为10进制的数才能具体知道是多少)。
三、最后提供一个数据库自定义函数,来计算此转换
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
DBCC IND(数据库名, 表名, -1)
可以快速获取文件号和页号,但是这个方法微软并未公开,可能在以后的版本中不适用