深入研究B樹索引(二)
2. B樹索引的內部結構
我們可以使用如下方式將B樹索引轉儲成樹狀結構的形式而呈現出來:
alter session set events 'immediate trace name treedump level INDEX_OBJECT_ID';
比如,對於上面的例子來說,我們把建立在goodid上的名為idx_warecountd_goodid的索引轉儲出來。
SQL> select object_id from user_objects where object_name='IDX_WARECOUNTD_GOODID';
OBJECT_ID
----------
7378
SQL> alter session set events 'immediate trace name treedump level 7378';
開啟轉儲出來的檔案以後,我們可以看到類似下面的內容:
----- begin tree dump
branch: 0x180eb0a 25225994 (0: nrow: 9, level: 2)
branch: 0x180eca1 25226401 (-1: nrow: 405, level: 1)
leaf: 0x180eb0b 25225995 (-1: nrow: 359 rrow: 359)
leaf: 0x180eb0c 25225996 (0: nrow: 359 rrow: 359)
leaf: 0x180eb0d 25225997 (1: nrow: 359 rrow: 359)
leaf: 0x180eb0e 25225998 (2: nrow: 359 rrow: 359)
…………………
branch: 0x180ee38 25226808 (0: nrow: 406, level: 1)
leaf: 0x180eca0 25226400 (-1: nrow: 359 rrow: 359)
leaf: 0x180eca2 25226402 (0: nrow: 359 rrow: 359)
leaf: 0x180eca3 25226403 (1: nrow: 359 rrow: 359)
leaf: 0x180eca4 25226404 (2: nrow: 359 rrow: 359)
…………………
其中,每一行的第一列表示節點型別:branch表示分支節點(包括根節點),而leaf則表示葉子節點;第二列表示十六進位制表示的節點的地址;第三列表示十進位制表示的節點的地址;第四列表示相對於前一個節點的位置,根節點從0開始計算,其他分支節點和葉子節點從-1開始計算;第五列的nrow表示當前節點中所含有的索引條目的數量。比如我們可以看到根節點中含有的nrow為9,表示根節點中含有9個索引條目,分別指向9個分支節點;第六列中的level表示分支節點的層級,對於葉子節點來說level都是0。第六列中的rrow表示有效的索引條目(因為索引條目如果被刪除,不會立即被清除出索引塊中。所以nrow減rrow的數量就表示已經被刪除的索引條目數量)的數量,比如對於第一個leaf來說,其rrow為359,也就是說該葉子節點中存放了359個可用索引條目,分別指向表warecountd的359條記錄。
上面這種方式以樹狀形式轉儲整個索引。同時,我們可以轉儲一個索引節點來看看其中存放了些什麼。轉儲的方式為:
alter system dump datafile file# block block#;
我們從上面轉儲結果中的第二行知道,索引的根節點的地址為25225994,因此我們先將其轉換為檔案號以及資料塊號。
SQL> select dbms_utility.data_block_address_file(25225994),
2 dbms_utility.data_block_address_block(25225994) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------ ------------------------------
6 60170
於是,我們轉儲根節點的內容。
SQL> alter system dump datafile 6 block 60170;
開啟轉儲出來的跟蹤檔案,我們可以看到如下的索引頭部的內容:
header address 85594180=0x51a1044
kdxcolev 2
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: pcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 8
kdxcofbo 44=0x2c
kdxcofeo 7918=0x1eee
kdxcoavs 7874
kdxbrlmc 25226401=0x180eca1
kdxbrsno 0
kdxbrbksz 8060
其中的kdxcolev表示索引層級號,這裡由於我們轉儲的是根節點,所以其層級號為2。對葉子節點來說該值為0;kdxcolok表示該索引上是否正在發生修改塊結構的事務;kdxcoopc表示內部操作程式碼;kdxconco表示索引條目中列的數量;kdxcosdc表示索引結構發生變化的數量,當你修改表裡的某個索引鍵值時,該值增加;kdxconro表示當前索引節點中索引條目的數量,但是注意,不包括kdxbrlmc指標;kdxcofbo表示當前索引節點中可用空間的起始點相對當前塊的位移量;kdxcofeo表示當前索引節點中可用空間的最尾端的相對當前塊的位移量;kdxcoavs表示當前索引塊中的可用空間總量,也就是用kdxcofeo減去kdxcofbo得到的。kdxbrlmc表示分支節點的地址,該分支節點存放了索引鍵值小於row#0(在轉儲文件後半部分顯示)所含有的最小值的所有節點資訊;kdxbrsno表示最後一個被修改的索引條目號,這裡看到是0,表示該索引是新建的索引;kdxbrbksz表示可用資料塊的空間大小。實際從這裡已經可以看到,即便是PCTFREE設定為0,也不能用足8192位元組。
再往下可以看到如下的內容。這部分內容就是在根節點中所記錄的索引條目,總共是8個條目。再加上
row#0[8043] dba: 25226808=0x180ee38
col 0; len 8; (8): 31 30 30 30 30 33 39 32
col 1; len 3; (3): 01 40 1a
……
row#7[7918] dba: 25229599=0x180f91f
col 0; len 8; (8): 31 30 30 31 31 32 30 33
col 1; len 4; (4): 01 40 8f a5
kdxbrlmc所指向的第一個分支節點,我們知道該根節點中總共存放了9個分支節點的索引條目,而這正是我們在前面所指出的為了管理3611個葉子節點,我們需要9個分支節點。
每個索引條目都指向一個分支節點。其中col 1表示所連結的分支節點的地址,該值經過一定的轉換以後實際就是row#所在行的dba的值。如果根節點下沒有其他的分支節點,則col 1為TERM;col 0表示該分支節點所連結的最小鍵值。其轉換方式非常複雜,比如對於row #0來說,col 0為31 30 30 30 30 30 30 33,則將其中每對值都使用函式to_number(NN,’XX’)的方式從十六進位制轉換為十進位制,於是我們得到轉換後的值:49,48,48,48,48,48,48,51,因為我們已經知道索引鍵值是char型別的,所以對每個值都運用chr函式就可以得到被索引鍵值為:10000003。實際上,對10000003運用dump函式得到的結果就是:49,48,48,48,48,48,48,51。所以我們也就知道,10000003就是dba為25226808的索引塊所連結的最小鍵值。
SQL> select dump('10000003') from dual;
DUMP('10000003')
-------------------------------------
Typ=96 Len=8: 49,48,48,48,48,48,48,50
接下來,我們從根節點中隨便找一個分支節點,假設就是row#0所描述的25226808。對其運用前面所介紹過的dbms_utility裡的儲存過程獲得其檔案號和資料塊號,並對該資料塊進行轉儲,其內容如下所示。可以
row#0[8043] dba: 25226402=0x180eca2
col 0; len 8; (8): 31 30 30 30 30 33 39 33
col 1; len 3; (3): 01 40 2e
………
row#404[853] dba: 25226806=0x180ee36
col 0; len 8; (8): 31 30 30 30 31 36 34 30
col 1; len 3; (3): 01 40 09
----- end of branch block dump -----
發現內容與根節點完全類似,只不過該索引塊中所包含的索引條目(指向葉子節點)的數量更多了,為405個。這也與我們前面所說的一個分支索引塊可以存放大約405(6488/16)個索引條目完全一致。
然後,我們從中隨便挑一個葉子節點,對其進行轉儲。假設就選row#0行所指向的葉子節點,根據dba的值:25226402可以知道,檔案號為6,資料塊號為60578。將其轉儲以後,其內容如下所示,我只顯示與分支節點不同的部分。
………
kdxlespl 0
kdxlende 0
kdxlenxt 25226403=0x180eca3
kdxleprv 25226400=0x180eca0
kdxledsz 0
kdxlebksz 8036
其中的kdxlespl表示當葉子節點被拆分時未提交的事務數量;kdxlende表示被刪除的索引條目的數量;kdxlenxt表示當前葉子節點的下一個葉子節點的地址;kdxlprv表示當前葉子節點的上一個葉子節點的地址;kdxledsz表示可用空間,目前是0。
轉儲檔案中接下來的部分就是索引條目部分,每個條目包含一個ROWID,指向一個表裡的資料行。如下所示。其中flag表示標記,比如刪除標記等;而lock表示鎖定資訊。col 0表示索引鍵值,其演算法與我們在前面介紹分支節點時所說的演算法一致。col 1表示ROWID。我們同樣可以看到,該葉子節點中包含了359個索引條目,與我們前面所估計的一個葉子節點中大約可以放360個索引條目也是基本一致的。
row#0[8018] flag: -----, lock: 0
col 0; len 8; (8): 31 30 30 30 30 33 39 33
col 1; len 6; (6): 01 40 2e 93 00 16
row#1[8000] flag: -----, lock: 0
col 0; len 8; (8): 31 30 30 30 30 33 39 33
col 1; len 6; (6): 01 40 2e e7 00 0e
…………
row#358[1574] flag: -----, lock: 0
col 0; len 8; (8): 31 30 30 30 30 33 39 37
col 1; len 6; (6): 01 40 18 ba 00 1f
----- end of leaf block dump -----
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9842/viewspace-321866/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 雜湊,二叉樹,紅黑樹,B樹,B+樹,LSM樹等資料結構做索引比較二叉樹資料結構索引
- Oracle中的B樹索引Oracle索引
- Oracle如何建立B樹索引Oracle索引
- 平衡二叉樹,B樹,B+樹二叉樹
- 二叉樹、B樹以及B+樹二叉樹
- Oracle如何實現B樹索引Oracle索引
- 搞懂MySQL InnoDB B+樹索引MySql索引
- 淺談MySQL的B樹索引與索引優化MySql索引優化
- 【Mysql】InnoDB 中的 B+ 樹索引MySql索引
- Mysql InnoDB B+樹索引和雜湊索引的區別? MongoDB 為什麼使用B-樹?MySql索引MongoDB
- 資料結構之樹結構概述(含滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜尋樹、紅黑樹、B-樹、B+樹、B*樹)資料結構二叉樹
- 談談InnoDB中的B+樹索引索引
- MySQL索引為什麼使用B+樹?MySql索引
- MySQL索引-B+樹(看完你就明白了)MySql索引
- Oracle如何管理帶約束的B樹索引Oracle索引
- 咬文嚼圖式的介紹二叉樹、B樹/B-樹二叉樹
- 跳槽必看MySQL索引:B+樹原理揭秘與索引優缺點分析MySql索引
- MySQL資料庫索引選擇使用B+樹MySql資料庫索引
- mysql索引為啥要選擇B+樹 (下)MySql索引
- mysql索引為啥要選擇B+樹 (上)MySql索引
- BST(二叉搜尋樹)、AVL樹、紅黑樹、2-3樹、B樹、B+樹、LSM樹、Radix樹比較
- Elasticsearch 中為什麼選擇倒排索引而不選擇 B 樹索引Elasticsearch索引
- 資料結構之MySQL獨愛B+樹(二叉樹、AVL樹、紅黑樹、B樹對比)資料結構MySql二叉樹
- B樹在資料庫索引中的應用剖析資料庫索引
- 面試題:MySQL索引為什麼用B+樹?面試題MySql索引
- 面試 (MySQL 索引為啥要選擇 B+ 樹)面試MySql索引
- 一分鐘掌握MySQL的InnoDB引擎B+樹索引MySql索引
- Mysql索引資料結構為什麼是B+樹?MySql索引資料結構
- 徹底搞懂MySQL為什麼要使用B+樹索引MySql索引
- 資料庫索引為什麼用B+樹實現?資料庫索引
- MySQL為什麼採用B+樹作為索引結構?MySql索引
- 主鍵為聯合主鍵時,索引B+樹結構索引
- B樹與B+樹區別辨析
- B-tree索引索引
- LeetCode題解(Offer26):判斷二叉樹A是否為二叉樹B的子樹(Python)LeetCode二叉樹Python
- 多路查詢樹(2-3 樹、2-3-4 樹、B 樹、B+ 樹)
- B 樹和 B+樹的區別, 為什麼 MySQL 要使用 B+樹MySql
- 為什麼選擇b+樹作為儲存引擎索引結構儲存引擎索引