B樹索引的內部結構

n-lauren發表於2013-03-07
為了觀察B樹索引的內部結構,首先建立一個實驗用的例子:
create table tindex as select * from dba_objects where 1=2;
 
insert into tindex select * from dba_objects;
UPDATE TINDEX SET OBJECT_NAME=ROWNUM;
commit;
DROP INDEX TST_IDX;
create index tst_idx on tindex (object_name);
然後在SYS使用者下,使用下面的指令碼找到索引所在的塊號,並把前面的3塊匯出:
SQL> COL SEGMENT_NAME FORMAT A30 TRUNCATE;
SQL> select segment_name,extent_id,file_id,block_id
  2  from dba_extents  where segment_name = 'TST_IDX' AND WNER='TEST';
 
SEGMENT_NAME             EXTENT_ID    FILE_ID   BLOCK_ID
------------------------------ ---------- ---------- ----------
TST_IDX                                 0         10      20097
TST_IDX                                 1         10      20249
TST_IDX                                 2         10      20281
TST_IDX                                 3         10      20313
TST_IDX                                 4         10      20345
TST_IDX                                 5         10      20377
TST_IDX                                 6         10      20393
TST_IDX                                 7         10      20401
TST_IDX                                 8         10      20409
TST_IDX                                 9         10      20417
 
已選擇10行。
alter system dump datafile 10 block 20097;
alter system dump datafile 10 block 20098;
alter system dump datafile 10 block 20099;
其中,20097是段頭的資訊,我們就不進行詳細的分析了。20098是整個索引的根,列出部分重要的資訊,然後我們來進行分析:
Start dump data blocks tsn: 10 file#: 10 minblk 20098 maxblk 20098
buffer tsn: 10 rdba: 0x02804e82 (10/20098)
scn: 0x0000.0025f32c seq: 0x01 flg: 0x00 tail: 0xf32c0601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data –塊的型別是資料塊
Block header dump:  0x02804e82
 Object id on Block? Y
 seg/obj: 0x91a9  csc: 0x00.25f31f  itc: 1  flg: -  typ: 2 – INDEX –物件的類別是索引
     fsl: 0  fnx: 0x0 ver: 0x01
 --下面是事務槽的情況
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn 0x0000.0025f31f
 
Branch block dump
=================
header address 139726916=0x8541044
kdxcolev 1
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: pcode=0: iot flags=--- is converted=Y
kdxconco 2 –列數為2,說明有一個鍵值
kdxcosdc 0
kdxconro 76 –根節點有76條記錄
kdxcofbo 180=0xb4
kdxcofeo 7246=0x1c4e
kdxcoavs 7066
kdxbrlmc 41963139=0x2804e83  --第一個葉節點的地址(存放最小的鍵值的資料)
kdxbrsno 0
kdxbrbksz 8060
row#0[8049] dba: 41963140=0x2804e84 ----第一個鍵值索引的下級塊地址,該地址包含的是大於等於第一個鍵值的第一個下級節點的地址
col 0; len 5; (5):  31 30 33 38 30  ----第一個鍵值範圍10380
col 1; TERM
row#1[8038] dba: 41963141=0x2804e85
col 0; len 5; (5):  31 30 37 36 33 ----第二個鍵值範圍10763
col 1; TERM
從上面的資料可以看出,第一個葉節點是0X02804E83,存放最小鍵值開始的資料。“10380”以上鍵值的記錄的下一級節點是0X02804E84(20100),以下是該節點的資料:
buffer tsn: 10 rdba: 0x02804e84 (10/20100)
……
Leaf block dump
===============
header address 139726940=0x854105c
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: pcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 425
kdxcofbo 886=0x376
kdxcofeo 1707=0x6ab
kdxcoavs 821
kdxlespl 0
kdxlende 0
kdxlenxt 41963141=0x2804e85  --下一個葉節點的地址
kdxleprv 41963139=0x2804e83  --前一個葉節點的地址
kdxledsz 0
kdxlebksz 8036
row#0[8021] flag: -----, lock: 0  --第一條記錄
col 0; len 5; (5):  31 30 33 38 30  --鍵值是10380
col 1; len 6; (6):  02 80 50 13 00 19  --表中記錄的地址(RDBA)是0x02805013(10/20499),第19條記錄
row#1[8006] flag: -----, lock: 0
col 0; len 5; (5):  31 30 33 38 31
col 1; len 6; (6):  02 80 50 13 00 1a
row#2[7991] flag: -----, lock: 0
col 0; len 5; (5):  31 30 33 38 32
col 1; len 6; (6):  02 80 50 13 00 1b
row#3[7976] flag: -----, lock: 0
col 0; len 5; (5):  31 30 33 38 33
col 1; len 6; (6):  02 80 50 13 00 1c
row#4[7961] flag: -----, lock: 0
col 0; len 5; (5):  31 30 33 38 34
col 1; len 6; (6):  02 80 50 13 00 1d
row#5[7946] flag: -----, lock: 0
col 0; len 5; (5):  31 30 33 38 35
col 1; len 6; (6):  02 80 50 13 00 1e
….
….
row#423[1722] flag: -----, lock: 0
col 0; len 5; (5):  31 30 37 36 31
col 1; len 6; (6):  02 80 50 18 00 2d
row#424[1707] flag: -----, lock: 0
col 0; len 5; (5):  31 30 37 36 32
col 1; len 6; (6):  02 80 50 18 00 2e
----- end of leaf block dump -----
End dump data blocks tsn: 10 file#: 10 minblk 20100 maxblk 20100
可以看出這個節點是葉節點,其中有一個葉節點連結串列的資訊十分重要:
kdxlenxt 41963141=0x2804e85  --下一個葉節點的地址
kdxleprv 41963139=0x2804e83  --前一個葉節點的地址
這個節點中,每條記錄直接儲存了鍵值對應的表的地址。看第一條記錄:
row#0[8021] flag: -----, lock: 0  --第一條記錄
col 0; len 5; (5):  31 30 33 38 30  --鍵值是10380
col 1; len 6; (6):  02 80 50 13 00 19  --表中記錄的地址(RDBA)是0x02805013(10/20499),第25號記錄
下面來核對10號檔案中的20499塊的第25號記錄:
ALTER SYSTEM DUMP DATAFILE 10 BLOCK 20499;
我們略過其他資訊,直接檢視25號記錄的資訊:
tab 0, row 25, @0x179b
tl: 79 fb: --H-FL-- lb: 0x2  cc: 13
col  0: [ 3]  53 59 53 – ascii碼:SYS
col  1: [ 5]  31 30 33 38 30  --ascii碼:10380
col  2: *NULL*
col  3: [ 4]  c3 02 19 5f  --number型別資料:12494
col  4: *NULL*
col  5: [10]  4a 41 56 41 20 43 4c 41 53 53
col  6: [ 7]  78 68 06 1b 0f 1b 18
col  7: [ 7]  78 68 06 1b 0f 1b 18
col  8: [19]  32 30 30 34 2d 30 36 2d 32 37 3a 31 34 3a 32 36 3a 32 33
col  9: [ 5]  56 41 4c 49 44
col 10: [ 1]  4e
col 11: [ 1]  4e
col 12: [ 1]  4e

通過下面的查詢可以驗證索引的結果:
SQL> select owner,object_name,object_id from tindex where object_name='10380';
 
OWNER   OBJECT_NAME  OBJECT_ID
------------------------------------------------------------------------------
SYS       10380           12494
和DUMP出來的資料完全一致。

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

相關文章