当前位置: 代码迷 >> Sql Server >> 【SQL Server2005页面储存4之-非聚集索引行在叶级别存储】
  详细解决方案

【SQL Server2005页面储存4之-非聚集索引行在叶级别存储】

热度:27   发布时间:2016-04-24 19:01:01.0
【SQL Server2005页面存储4之--非聚集索引行在叶级别存储】
全文参看博文地址:http://blog.csdn.net/feixianxxx/archive/2010/05/08/5569945.aspx

非聚集索引行在叶级别存储的时候也分在堆上、在聚集索引的表上.

一:堆上的非聚集索引在叶级别的存储
/*----------------------------------------------------------------------
*auther:Poofly
*date:2010.3.14
*VERSION:
Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) 
Jul  9 2008 14:43:34 
Copyright (c) 1988-2008 Microsoft Corporation
Enterprise Evaluation Edition on Windows NT 6.1 <X86> (Build 7600: )
*转载请注明出处
*更多精彩内容,请进http://blog.csdn.net/feixianxxx
------------------------------------------------------------------------*/
--建表(表源技术内幕)
CREATE TABLE NC_Heap_Nodupes (
  id int NOT NULL ,
  str1 char (5) NOT NULL ,
  str2 char (600) NULL ); 
GO
--在str1上建立非聚集索引
CREATE UNIQUE INDEX idxNC_heap ON NC_Heap_Nodupes (str1); 
GO
--插入数据
DECLARE @i int;
SET @i = 1240;
WHILE @i < 1300 BEGIN
  INSERT INTO NC_Heap_Nodupes 
   SELECT @i, cast(@i AS char), cast(@i AS char);
  SET @i = @i + 1;
 END; 
GO
--执行DBCC将结果插入表并显示相关页号
TRUNCATE TABLE sp_table_pages;
INSERT INTO sp_table_pages
    EXEC ('dbcc ind ( poofly, NC_Heap_Nodupes, -1)'  );
SELECT PageFID, PagePID, IndexID, IndexLevel, PageType 
FROM sp_table_pages
WHERE IndexLevel >= 0;

/*
PageFID PagePID     IndexID IndexLevel PageType
------- ----------- ------- ---------- --------
5       52          0       0          1           --pagetype 1 数据分页2索引分页
5       54          2       0          2           --IndexID 0为堆 1为聚集索引2-250为非聚集索引    
5       952         0       0          1
5       953         0       0          1
5       954         0       0          1
5       955         0       0          1
5       956         0       0          1
*/
go
我们从结果可以看到由于数据行的量比较少只有行 所以我们只需要一个索引页来存储.
IndexID为 PageType为 说明它是一个存储非聚集索引的索引分页,IndexLevel为 说明是叶级别的

--来看看这个页面的存储特点:
dbcc traceon(3604);
dbcc page(poofly,5,54,1)
/*
Slot 0, Offset 0x60, Length 14, DumpStyle BYTE

00000000:   06313234 30203400 00000500 0000??????.1240 4.......           

Slot 1, Offset 0x6e, Length 14, DumpStyle BYTE

00000000:   06313234 31203400 00000500 0100??????.1241 4.......      
....
Slot 59, Offset 0x39a, Length 14, DumpStyle BYTE

00000000:   06313239 3920bc03 00000500 0400??????.1299 ........           
*/

--先来看第一条索引行Slot 0
06->状态位A(没有状态位B在索引行中)
313234 3020->=='1240 ' 它是一个非聚集值
3400 0000->Ox0034=52 这个书签的分页指针指向的页号 52
0500->书签的文件ID
0000->书签的槽号(行号,从开始)
--第二条和第一条的区别
313234 3120->=='1241 '
3400 00000500 0100->这个字节其实就是一个完整的书签 我们发现这个和上面记录的区别就是最后的书签的槽号(行号)不同,因为是条记录嘛
--最后一条索引记录
313239 3920->=='1299 ' 我们发现它的值就是我们表内的最后一条记录的非聚集值
bc03 0000->Ox03bc==956 我们可以看这个页号,这个存储我们表内最后一条记录的页号不就是么?
    0500->文件号 
0400->说明我们的这条记录在页里面是第五条记录
 
--我们来验证下上面的假设
dbcc page(poofly,5,956,1)
/*
Slot 4, Offset 0xa00, Length 616, DumpStyle BYTE  ...

00000000:   10006502 13050000 31323939 20313239 ?.e.....1299 129         
00000010:   39202020 20202020 20202020 20202020 ?                        
  相关解决方案