表1结构及数据
1
USE testdb
2
GO
3
/*
***************************************
4
堆存储_01
5
Phoenix.Feng 2010-11-18
6
***************************************
*/
7
IF
OBJECT_ID(
'
IDF_Heap_01
')
IS
NOT
NULL
8
DROP
TABLE IDF_Heap_01
9
GO
10
CREATE
TABLE IDF_Heap_01(
11 id
INT,
12 name
NCHAR(
2017)
13 )
14
INSERT
INTO IDF_Heap_01
VALUES(
1,
'
phoenix
')
15
INSERT
INTO IDF_Heap_01
VALUES(
2,
'
kevin
')
16
INSERT
INTO IDF_Heap_01
VALUES(
3,
'
YY
')
17
INSERT
INTO IDF_Heap_01
VALUES(
4,
'
TERRY
')
表二结构及数据
1
/*
***************************************
2
堆存储_02
3
Phoenix.Feng 2010-03-16
4
***************************************
*/
5
IF
OBJECT_ID(
'
IDF_Heap_02
')
IS
NOT
NULL
6
DROP
TABLE IDF_Heap_02
7
GO
8
CREATE
TABLE IDF_Heap_02(
9 id
INT,
10 name
NCHAR(
2018)
11 )
12
INSERT
INTO IDF_Heap_02
VALUES(
1,
'
phoenix
')
13
INSERT
INTO IDF_Heap_02
VALUES(
2,
'
kevin
')
14
INSERT
INTO IDF_Heap_02
VALUES(
3,
'
YY
')
15
INSERT
INTO IDF_Heap_02
VALUES(
4,
'
TERRY
')
16
GO
我在这里创建了两张表,他们看起来似乎没有任何区别,只是第一张表中列name的字符串长度是2017,后面是2018,但是通过查看IAM分配的情况, 结果让人很是意外;
首先创建页地址转具体页码函数
IF OBJECT_ID('f_get_page') IS NOT NULL
DROP FUNCTION f_get_page
GO
CREATE FUNCTION 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
GO
查询语句
1 SELECT total_pages,used_pages,data_pages,
2 first_page,root_page,first_iam_page,
3 dbo.f_get_page(first_page) first_page,
4 dbo.f_get_page(root_page) root_page,
5 dbo.f_get_page(first_iam_page) first_iam_page
6
FROM sys.system_internals_allocation_units
7
WHERE container_id
IN (
8
SELECT partition_id
FROM sys.partitions
9
WHERE
object_id
in(
10
SELECT
object_id
FROM sys.objects
WHERE name
=
'
IDF_Heap_01
'
11 )
12 )
13
GO
14
SELECT total_pages,used_pages,data_pages,
15 first_page,root_page,first_iam_page,
16 dbo.f_get_page(first_page) first_page,
17 dbo.f_get_page(root_page) root_page,
18 dbo.f_get_page(first_iam_page) first_iam_page
19
FROM sys.system_internals_allocation_units
20
WHERE container_id
IN (
21
SELECT partition_id
FROM sys.partitions
22
WHERE
object_id
in(
23
SELECT
object_id
FROM sys.objects
WHERE name
=
'
IDF_Heap_02
'
24 )
25 )
26
GO
这里显示查询结果:
第二张表中,name仅比第一张表大一个长度,但他所使用的数据页是前者的两倍,即一条数据一页。
其实原因很简单,表2中每行数据的大小刚好超过sql server中每页存储大小为8096一半的边界值,参考来至MSDN。