索引的INTERNAL 研究系列 之通過TREEDUMP檢視二叉樹索引的結構

kewin發表於2011-08-29
索引的INTERNAL 研究系列 之通過TREEDUMP檢視二叉樹索引的結構
Kevin Zou
2011-8-29
一直覺得對索引的資料儲存理解不深,很多時候都是知其然不知其所然,趁現在有時間來研究一下。
覺得要真正研究透索引特性,索引的儲存,要看很多的資料,做很多的測試。
現在開始,爭取在一個月內完成。

如果要看索引在資料庫內的儲存總概述,可以通過TREEDUMP 命令來檢視。 
先找到索引的物件ID,然後通過 ALTER SESSION SET EVENTS 'immediate trace name TREEDUMP level OBJECT_ID' 來DUMP TREEMAP。
SQL> select segment_name, file_id, blocks, block_id 
  2   from dba_extents
  3    where segment_name='I_TEST' and wner='SYS';

SEGMENT_NAME            FILE_ID     BLOCKS   BLOCK_ID
-------------------- ---------- ---------- ----------
I_TEST                        1          8      37641
I_TEST                        1          8      37649
I_TEST                        1          8      37657
I_TEST                        1          8      37665
SQL> select object_id from dba_objects where object_name='I_TEST';

 OBJECT_ID
----------
     65949
SQL> ALTER SESSION SET EVENTS 'immediate trace name TREEDUMP level  65949';
Session altered.

----- begin tree dump
branch: 0x40930a 4231946 (0: nrow: 29, level: 1)
   leaf: 0x40930b 4231947 (-1: nrow: 485 rrow: 485)
   leaf: 0x40930c 4231948 (0: nrow: 479 rrow: 479)
   leaf: 0x40930d 4231949 (1: nrow: 478 rrow: 478)
   leaf: 0x40930e 4231950 (2: nrow: 479 rrow: 479)
   leaf: 0x40930f 4231951 (3: nrow: 479 rrow: 479)
   leaf: 0x409310 4231952 (4: nrow: 479 rrow: 479)
   leaf: 0x409311 4231953 (5: nrow: 479 rrow: 479)
   leaf: 0x409312 4231954 (6: nrow: 478 rrow: 478)
   leaf: 0x409313 4231955 (7: nrow: 479 rrow: 479)
   leaf: 0x409314 4231956 (8: nrow: 479 rrow: 479)
   leaf: 0x409315 4231957 (9: nrow: 479 rrow: 479)
   leaf: 0x409316 4231958 (10: nrow: 479 rrow: 479)
   leaf: 0x409317 4231959 (11: nrow: 479 rrow: 479)
   leaf: 0x409318 4231960 (12: nrow: 479 rrow: 479)
   leaf: 0x409319 4231961 (13: nrow: 479 rrow: 479)
   leaf: 0x40931a 4231962 (14: nrow: 479 rrow: 479)
   leaf: 0x40931b 4231963 (15: nrow: 479 rrow: 479)
   leaf: 0x40931c 4231964 (16: nrow: 479 rrow: 479)
   leaf: 0x40931d 4231965 (17: nrow: 471 rrow: 471)
   leaf: 0x40931e 4231966 (18: nrow: 449 rrow: 449)
   leaf: 0x40931f 4231967 (19: nrow: 449 rrow: 449)
   leaf: 0x409320 4231968 (20: nrow: 449 rrow: 449)
   leaf: 0x409321 4231969 (21: nrow: 449 rrow: 449)
   leaf: 0x409322 4231970 (22: nrow: 449 rrow: 449)
   leaf: 0x409323 4231971 (23: nrow: 448 rrow: 448)
   leaf: 0x409324 4231972 (24: nrow: 448 rrow: 448)
   leaf: 0x409325 4231973 (25: nrow: 449 rrow: 449)
   leaf: 0x409326 4231974 (26: nrow: 449 rrow: 449)
   leaf: 0x409327 4231975 (27: nrow: 404 rrow: 404)
----- end tree dump

DUMP出來的檔案描述了索引分佈在哪些BLOCK中,每個BLOCK的屬於LEAF還是BRANCHE節點,每個block中的內容。
結構說明:
branch/leaf代表該行是分支節點還是頁節點(第一行的branch其實是root節點):
branch: 表示該資料塊是branch block (第一行的branch其實是root節點 )
leaf: 表示該資料塊是leaf block
該節點的rdba,前面是16進位制的,後面是10進位制的:
0x40930a: 對應索引資料塊的十六進位地址;
4231946:對應索引資料塊的十進位地址
括號裡的第一個數字是同一個level的節點位置計數,root節點從0開始,其他的level從-1開始。 
節點中當前的index entry數,從這兩個值可以分析出index的空間使用效率;
nrow: 485 :表示該索引資料塊中總的行數,包含被刪除的行;
rrow: 485:表示該索引資料塊中實際存在有效行數

一般每個索引物件儲存塊SEGMENT HEADER後第一塊,就是ROOT BLOCK。
我這裡I_TEST物件的儲存的BLOCK是從37641開始分配的空間,連續的32個block。一般索引是SEGMENT HEADER佔一個BLOCK(這個未經證實),而第二block=37641+1=37642就是root block.也是我們從TREEDUMP 中看到的第一個branch block的地址。
葉節點有個隱含的level引數,該引數值等於0,也就是說葉節點level 是從0開始的。一直往上直到root 節點。
除了可以看trace檔案來看BLEVEL的深度,也可以通過資料字典來檢視:
SQL> SELECT blevel FROM dba_indexes WHERE index_name = 'I_TEST';

    BLEVEL
----------
         1
那整個INDEX的高度計算公式是HEIGHT=BLEVEL+ 1;這個需要通過index_stats 試圖來檢視,檢視前需要先分析下索引結構
SQL> ANALYZE INDEX I_TEST VALIDATE STRUCTURE;

Index analyzed.

SQL> select height from index_stats where name ='I_TEST';

    HEIGHT
----------
         2
得到BLOCK的地址後,可以通過dbms_utility package 來查詢對應的FILE和BLOCK:
SQL> select dbms_utility.data_block_address_file(4231946) "file",dbms_utility.data_block_address_block(4231946) "block"  from dual;

      file      block
---------- ----------
         1      37642

-THE END-

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/40239/viewspace-706133/,如需轉載,請註明出處,否則將追究法律責任。

相關文章