首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 2008 儲存結構深度解析:非叢集索引

     編輯:關於SqlServer

非叢集索引 vs 叢集索引核心差異

特性叢集索引非叢集索引
資料排序依叢集鍵值邏輯排序儲存資料不依非叢集鍵排序
葉層結構資料頁索引頁 (含鍵值+行定位器)
每張表數量最多 1 個最多 999 個 (2008)

行定位器

非叢集索引葉層每列包含:非叢集鍵值 + 行定位器

基礎表結構行定位器類型內容
堆疊表RID (Row ID)檔案號:頁碼:列號 (4+2+2=8 bytes)
叢集索引表叢集鍵值叢集索引鍵值 (若不唯一,內部加 4 bytes 唯一化值)

堆疊表上的非叢集索引實測

-- 建立測試堆疊表
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');
-- ... 共 10 筆

查詢索引頁面資訊

-- 取得物件與索引對應
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';

-- 使用 DBCC IND 取得頁面分配
TRUNCATE TABLE tablepage;
INSERT INTO tablepage EXEC ('DBCC IND(testdb,testHeapIndex,0)'); -- 堆疊
INSERT INTO tablepage EXEC ('DBCC IND(testdb,testHeapIndex,2)'); -- 索引 2
INSERT INTO tablepage EXEC ('DBCC IND(testdb,testHeapIndex,3)'); -- 索引 3

-- 查詢頁面類型與層級
SELECT b.name table_name, 
       CASE c.type WHEN 0 THEN '堆疊' WHEN 1 THEN '叢集' WHEN 2 THEN '非叢集' END index_type,
       c.name index_name, PagePID, IAMPID, 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

根頁面查詢

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

B+ 樹結構特性

  • 根節點 → 中間層 → 葉層
  • 葉層透過雙向鏈表連結 (NextPagePID, PrevPagePID)
  • IndexLevel 0 = 葉層,遞增向根
  • sys.system_internals_allocation_units.root_page 指向根頁面

實務啟示

  1. 非叢集索引鍵值越窄越好 (少欄位、窄資料類型)
  2. 叢集鍵值會複製到所有非叢集索引葉層,故叢集鍵宜窄、唯一、不常更新
  3. 堆疊表 RID 查找需額外 I/O,叢集索引表透過鍵值查找通常較佳
  4. 覆蓋索引可避免鍵值查找,大幅提升查詢效能
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved