表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')
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
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
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。