合理设计列的长度

 表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

posted @ 2013-01-21 23:41  冯翔  阅读(260)  评论(0编辑  收藏  举报