加入收藏 | 设为首页 | 会员中心 | 我要投稿 宁德站长网 (https://www.0593zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQL Server 2008存储结构之非聚集索引

发布时间:2016-09-03 04:18:14 所属栏目:MsSql教程 来源:站长网
导读:非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点: 基础表的数据行不按非聚集键的顺序排序和存储。 非聚集索引的叶层是由索引页而不
非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点:

基础表的数据行不按非聚集键的顺序排序和存储。

非聚集索引的叶层是由索引页而不是由数据页组成。

非聚集索引既可以建在堆表结构上也可以建在聚集索引表上;非聚集索引中的每个索引行都包含非聚集键值和行定位符。此定位符指向聚集索引或堆中包含该键值的数据行。

如果表是堆则行定位器是指向行的指针。该指针由文件标识符 (ID)、页码和页上的行数生成。整个指针称为行 ID (RID)。

如果表包含有聚集索引,则行定位器是行的聚集索引键。如果聚集索引不是唯一的索引,SQL Server 将添加在内部生成的值(称为唯一值)以使所有重复键唯一。此四字节的值对于用户不可见。仅当需要使聚集键唯一以用于非聚集索引中时,才添加该值。SQL Server 通过使用存储在非聚集索引的叶行内的聚集索引键搜索聚集索引来检索数据行。

B 树的页集合由 sys.system_internals_allocation_units 系统视图中的 root_page 指针定位。

SQL Server 2008存储结构之非聚集索引

堆表

--创建一张堆表
    
CREATE TABLE testHeapIndex
    
(
    
   name   CHAR(200),
    
   type1  CHAR(900),
    
   type2  CHAR(900)
    
)
    
--分别创建一个唯一索引和一个非唯一索引
    
CREATE UNIQUE INDEX idx_testHeapIndex1 ON testHeapIndex(type1)
    
CREATE INDEX idx_testHeapIndex2 ON testHeapIndex(type2)
    
--插入测试数据
    
INSERT INTO testHeapIndex VALUES('A','A1','A2')
    
INSERT INTO testHeapIndex VALUES('B','B1','B2')
    
INSERT INTO testHeapIndex VALUES('C','C1','B2')
    
INSERT INTO testHeapIndex VALUES('D','D1','B2')
    
INSERT INTO testHeapIndex VALUES('E','E1','C2')
    
INSERT INTO testHeapIndex VALUES('F','F1','F1')
    
INSERT INTO testHeapIndex VALUES('G','G1','G1')
    
INSERT INTO testHeapIndex VALUES('H','H1','G1')
    
INSERT INTO testHeapIndex VALUES('I','I1','G1')
    
INSERT INTO testHeapIndex VALUES('J','J1','J1')
    
--获取该表的相应页面信息
    
SELECT A.NAME TABLE_NAME,B.NAME INDEX_NAME,B.INDEX_ID
    
  FROM SYS.OBJECTS A,SYS.INDEXES B
    
 WHERE A.OBJECT_ID=B.OBJECT_ID AND A.NAME='testHeapIndex'
    
TRUNCATE TABLE tablepage;
    
INSERT INTO tablepage EXEC ('DBCC IND(testdb,testHeapIndex,0)');
    
INSERT INTO tablepage EXEC ('DBCC IND(testdb,testHeapIndex,2)');
    
INSERT INTO tablepage EXEC ('DBCC IND(testdb,testHeapIndex,3)');
    
SELECT
    
  b.name table_name,
    
  CASE WHEN c.type=0 THEN '堆'
    
       WHEN c.type=1 THEN '聚集'
    
       WHEN c.type=2 THEN '非聚集'
    
       ELSE '其他'
    
  END index_type, 
    
  c.name index_name,
    
  PagePID,IAMPID,ObjectID,IndexID,Pagetype,IndexLevel,
    
  NextPagePID,PrevPagePID
    
  FROM tablepage a,sys.objects b,sys.indexes c
    
 WHERE A.ObjectID=b.object_id
    
   AND A.ObjectID=c.object_id
    
   AND a.IndexID=c.index_id
    
--获取该表的root页面地址,聚集索引的根节点必须通过下面脚本才能找到
    
SELECT c.name,a.type_desc,d.name,
    
       total_pages,used_pages,data_pages,
    
       testdb.dbo.f_get_page(first_page) first_page_address,
    
       testdb.dbo.f_get_page(root_page) root_address,
    
       testdb.dbo.f_get_page(first_iam_page) IAM_address
    
  FROM sys.system_internals_allocation_units a,sys.partitions b,sys.objects c,sys.indexes d
    
 WHERE a.container_id=b.partition_id and b.object_id=c.object_id
    
   AND d.object_id=b.object_id  AND d.index_id=b.index_id
    
   AND c.name in ('testHeapIndex')
    
--下面各个例子获取相关页面和root页面的脚本基本相同,不再重复

(编辑:宁德站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读