從平衡樹到oracle b-tree索引的原理探索

來源:互聯網
上載者:User

    先話嘮一下,oracle索引,有兩類運用較廣:

    1)b-tree:OLTP(面向交易)
    2)bitmap:OLAP(面向分析)

    步入正題,先搭建測試環境:

SQL> create table tt as select * from dba_objects;表已建立。SQL> select count(*) from tt;  COUNT(*)----------     50441SQL> insert into tt select * from tt;已建立50441行。SQL> /已建立100882行。SQL> /已建立201764行。SQL> /已建立403528行。SQL> /已建立807056行。SQL> create index tt_index on tt(object_id) tablespace users;索引已建立。

    把索引tt_index的結構給dump出來:

SQL> select object_id from dba_objects where object_name='TT_INDEX'; OBJECT_ID----------     53042SQL> alter session set events 'immediate trace name treedump level 53042';會話已更改。SQL> show parameter user_dump_destNAME                                 TYPE------------------------------------ ----------------------VALUE------------------------------user_dump_dest                       stringG:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMPSQL> select distinct sid from v$mystat;       SID----------       147SQL> select paddr from v$session where sid=147;PADDR--------CA280DDCSQL> select spid from v$process where addr='CA280DDC';SPID------------------------5360

    到udump,把進程號為5360的檔案開啟,部分內容如下:

*** 2012-08-07 01:21:34.944*** ACTION NAME:() 2012-08-07 01:21:34.902*** MODULE NAME:(SQL*Plus) 2012-08-07 01:21:34.902*** SERVICE NAME:(SYS$USERS) 2012-08-07 01:21:34.902*** SESSION ID:(147.92) 2012-08-07 01:21:34.902----- begin tree dumpbranch: 0x10001bc 16777660 (0: nrow: 7, level: 2)   branch: 0x100595f 16800095 (-1: nrow: 578, level: 1)      leaf: 0x10001bd 16777661 (-1: nrow: 513 rrow: 513)      leaf: 0x10001be 16777662 (0: nrow: 513 rrow: 513)      leaf: 0x10001bf 16777663 (1: nrow: 513 rrow: 513)      leaf: 0x10001c0 16777664 (2: nrow: 513 rrow: 513)      leaf: 0x10001c1 16777665 (3: nrow: 513 rrow: 513)      leaf: 0x10001c2 16777666 (4: nrow: 513 rrow: 513)      leaf: 0x10001c3 16777667 (5: nrow: 484 rrow: 484)      leaf: 0x10001c4 16777668 (6: nrow: 478 rrow: 478)      leaf: 0x10001c5 16777669 (7: nrow: 478 rrow: 478)      leaf: 0x10001c6 16777670 (8: nrow: 478 rrow: 478)      leaf: 0x10001c7 16777671 (9: nrow: 478 rrow: 478)      leaf: 0x10001c8 16777672 (10: nrow: 478 rrow: 478)      leaf: 0x10001ca 16777674 (11: nrow: 481 rrow: 481)      leaf: 0x10001cb 16777675 (12: nrow: 478 rrow: 478)      leaf: 0x10001cc 16777676 (13: nrow: 478 rrow: 478)      leaf: 0x10001cd 16777677 (14: nrow: 478 rrow: 478)      leaf: 0x10001ce 16777678 (15: nrow: 478 rrow: 478)      leaf: 0x10001cf 16777679 (16: nrow: 478 rrow: 478)

    由此可證明:b-tree中的b是balance,是棵平衡樹。否則,一個branch下面只有兩個leaf,才是二叉樹。

    上面:0x10001bd (16進位)和16777661(10進位)這兩個,其實,是一樣的。

SQL> select to_number('10001bd','xxxxxxx') from dual;TO_NUMBER('10001BD','XXXXXXX')------------------------------                      16777661

    而且,16777661包含兩部分:檔案號、資料區塊號。意指:這個地址是哪個資料檔案上的第幾個塊

SQL> select dbms_utility.data_block_address_file( 16777661) from dualDBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(16777661)----------------------------------------------                                             4SQL> select dbms_utility.data_block_address_block( 16777661) from duaDBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(16777661)-----------------------------------------------                                            445

    由上,可得:4號檔案的第445個塊

    將tt_index的內容給dump出來一下:

SQL> alter system dump datafile 4 block 445;系統已更改。

    部分內容摘入如下:

row#0[8024] flag: ------, lock: 0, len=12col 0; len 2; (2):  c1 03col 1; len 6; (6):  01 00 01 ac 00 2drow#1[8012] flag: ------, lock: 0, len=12col 0; len 2; (2):  c1 03col 1; len 6; (6):  01 00 05 36 00 40row#2[8000] flag: ------, lock: 0, len=12col 0; len 2; (2):  c1 03col 1; len 6; (6):  01 00 08 01 00 1brow#3[7988] flag: ------, lock: 0, len=12col 0; len 2; (2):  c1 03col 1; len 6; (6):  01 00 0a a2 00 2drow#4[7976] flag: ------, lock: 0, len=12col 0; len 2; (2):  c1 03col 1; len 6; (6):  01 00 0d 69 00 48

    tt表最小的object_id為2,對應的便是row#0[8024],那麼2在oracle中的16進位是如何儲存的呢?

SQL> select dump(2,16) from dual;DUMP(2,16)----------------------------------Typ=2 Len=2: c1,3

    由此,可知:2的儲存是c1 03.也就是,第0行的第一列儲存的值是2.

    意味著,在索引的葉子節點裡,我們在哪一列上建立索引,其實,oracle就是把該列的值儲存到索引的葉子節點裡。

    索引裡第一行第2列16進位數:01 00 01 ac 00 2d和rowid有啥關係呢?

SQL> select object_id,rowid from tt  2   where object_id=2  3   order by object_id,rowid; OBJECT_ID ROWID---------- ------------------         2 AAAM8xAAEAAAAGsAAt         2 AAAM8xAAEAAAAU2ABA         2 AAAM8xAAEAAAAgBAAb         ...

    其實,索引裡第一行第2列16進位數:01 00 01 ac 00 2d表示的是rowid裡面後三部分,也就是:fno、bno、rno。

    rowid:AAAM8x  AAE  AAAAGs  AAt。通過進位的轉換,AAE  AAAAGs  AAt和01 00 01 ac 00 2d是一樣的。

    為什麼只有後三個部分呢?說白點,書的目錄會把書名給包括進去嗎?書名就是對象編號、目錄就是索引。

    到此,我們把索引的內部結構給構造出來:

    object_id  rowid(後三部分)

    ...             ...

    草圖如下:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.