日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Oracle B-Tree Index 原理

發布時間:2023/12/9 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle B-Tree Index 原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

. B-Tree Index 原理

官網說明:

?????? No index structure can satisfy all needs, but the self-balancing B-tree index comes closest to optimizing the performance of searches on large sets of data. Each B-tree node holds multiple keys and pointers. The maximum number of keys in a node supported by a specific B-tree is the order of that tree. Each node has a potential of order+1 pointers to the level below it.

?????? For example, the order=2 B-tree illustrated in Figure 7-1 has tree pointers: to child nodes whose value is less than the first key, to the child nodes whose value is greater than the first key and less than the second key, and to the child nodes whose value is greater than the second key. Thus, the B-tree algorithm minimizes the number of reads and writes necessary to locate a record by passing through fewer nodes than in a binary tree algorithm, which has only one key and at most two children for each decision node. Here we describe the Knuth variation in which the index consists of two parts: a sequence set that provides fast sequential access to the data, and an index set that provides direct access to the sequence set.

?????? Although the nodes of a B-tree generally do not contain the same number of data values, and they usually contain a certain amount of unused space, the B-tree algorithm ensures that the tree remains balanced and that the leaf nodes are at the same level.

?

?



?????? Oracle中的Btree Index具有3大結構,root節點,branch節點,leaf節點. Root節點始終緊跟索引段頭.? 當索引比較小的時候,root節點,branch節點,leaf節點都存儲在同一個block.

?

?????? Branch節點主要存儲了索引的鍵值,但是這個鍵值并不是完整的,它只是完整索引值的部分前綴.同時Branch節點還存儲了指向leaf節點的指針(DBA),另外有個主意的是branch節點中還有個叫kdxbrlmc的指針.

?

Oracle rdba dba 說明

http://blog.csdn.net/tianlesoftware/archive/2011/06/07/6529346.aspx

?

?????? Leaf節點主要存儲了完整的索引鍵值,以及相關索引鍵值的部分rowid(這個rowid去掉了data object number部分),同時leaf 節點還存儲了2個指針(DBA),他們分別指向上一個leaf節點以及下一個leaf節點.?

?

?????? Btree Index 是始終平衡的,也就是說 Root節點到 Leaf 節點的任何一個路徑都是等距離的.?

????? Btree Index 默認是按照索引值升序排列的,當然了我們可以在創建/重建的時候設置它降序排列.?

?

?????? Index Scan 的時候,采用的是 sequential read,并且一次只能讀一個block(INDEX FAST FULL SCAN 除外).??

?

?????? Btree Index Update 時候,先做的是 delete,然后進行insert.?

?

?????? Btree Index 不存儲 Null值,但是如果組合索引其中一列是非Null的,那么組合索引也會存儲Null.?

?

?

. Tree Index 存儲原理?

?

2.1 創建測試數據

SYS@anqing2(rac2)> select * from v$version where rownum=1;

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod

?

SYS@anqing2(rac2)> create table te as select * from? dba_objects;

Table created.

?

SYS@anqing2(rac2)> select count(*) from te;

? COUNT(*)

----------

?? 50258

?

SYS@anqing2(rac2)> insert into te select * from dba_objects;

50258 rows created.

?

SYS@anqing2(rac2)> commit;

Commit complete.

?

SYS@anqing2(rac2)> select count(*) from te;

? COUNT(*)

----------

??? 100516

?

SYS@anqing2(rac2)> create index idx_te_object_name on te(object_name);

Index created.

?

2.2 查看索引的Blevel, 可以通過DBA_INDEXES.Blevel獲得

*-Tree level: depth of the index from its root block to its leaf blocks. A depth of 0 indicates that the root block and leaf block are the same.?

?????? -- root block leaf block的深度. 如果root block leaf block在同一個塊中 那么 Blevel=0

?

SYS@anqing2(rac2)> select index_name,blevel from dba_indexes where index_name='IDX_TE_OBJECT_NAME';

INDEX_NAME???????????????????????? BLEVEL

------------------------------ ----------

IDX_TE_OBJECT_NAME????????????????????? 2

?

2.3 查看索引的height,索引的高度等于Blevel+1height可以通過INDEX_STATS獲得

?

SYS@anqing2(rac2)> select name,height from index_stats where name='IDX_TE_OBJECT_NAME';

no rows selected

--- index_stats需要 analyze ... validate structure 收集一下,否則無數據?

SYS@anqing2(rac2)>? analyze index IDX_TE_OBJECT_NAME validate structure;

Index analyzed.

SYS@anqing2(rac2)> select name,height from index_stats where name='IDX_TE_OBJECT_NAME';

NAME?????????????????????????????? HEIGHT

------------------------------ ----------

IDX_TE_OBJECT_NAME????????????????????? 3

?

?

2.4 dump index

?????? Oracle 提供了分析 Btree index 結構的命令 treedump,在進行treedump之前需要獲得索引的object_id

?

SYS@anqing2(rac2)> select object_id from dba_objects where object_name='IDX_TE_OBJECT_NAME' and owner='SYS';?

?OBJECT_ID

----------

???? 54769???

?

SYS@anqing2(rac2)> oradebug setmypid

Statement processed.

SYS@anqing2(rac2)> alter session set events 'immediate trace name treedump level 54769';?

Session altered.

?

SYS@anqing2(rac2)> oradebug tracefile_name

/u01/app/oracle/admin/anqing/udump/anqing2_ora_3865.trc

?

?

2.5 查看 treedump trace 文件?

[oracle@rac2 ~]$ cat /u01/app/oracle/admin/anqing/udump/anqing2_ora_3865.trc

/u01/app/oracle/admin/anqing/udump/anqing2_ora_3865.trc

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production

With the Partitioning, Real Application Clusters, OLAP, Data Mining

and Real Application Testing options

ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1

System name:??? Linux

Node name:????? rac2

Release:??????? 2.6.18-194.el5

Version:??????? #1 SMP Tue Mar 16 21:52:43 EDT 2010

Machine:??????? i686

Instance name: anqing2

Redo thread mounted by this instance: 2

Oracle process number: 29

Unix process pid: 3865, image: oracle@rac2 (TNS V1-V3)

?

*** 2011-06-27 13:15:00.375

*** ACTION NAME:() 2011-06-27 13:15:00.371

*** MODULE NAME:(sqlplus@rac2 (TNS V1-V3)) 2011-06-27 13:15:00.371

*** SERVICE NAME:(SYS$USERS) 2011-06-27 13:15:00.371

*** SESSION ID:(130.55497) 2011-06-27 13:15:00.371

----- begin tree dump

branch: 0x4117c2 4265922 (0: nrow: 2, level: 2)

?? branch: 0x412086 4268166 (-1: nrow: 250, level: 1)

??? ??leaf: 0x4117c3 4265923 (-1: nrow: 182 rrow: 182)

????? leaf: 0x4117c4 4265924 (0: nrow: 182 rrow: 182)

????? leaf: 0x4117c5 4265925 (1: nrow: 186 rrow: 186)

????? leaf: 0x4117c6 4265926 (2: nrow: 189 rrow: 189)

????? leaf: 0x4117c7 4265927 (3: nrow: 186 rrow: 186)

????? leaf: 0x4117c8 4265928 (4: nrow: 190 rrow: 190)

????? leaf: 0x4117c9 4265929 (5: nrow: 186 rrow: 186)

????? leaf: 0x4117ca 4265930 (6: nrow: 178 rrow: 178)

????? leaf: 0x4117cb 4265931 (7: nrow: 187 rrow: 187)

????? leaf: 0x4117cc 4265932 (8: nrow: 182 rrow: 182)

?? ??????? ......

????? leaf: 0x412080 4268160 (244: nrow: 222 rrow: 222)

????? leaf: 0x412081 4268161 (245: nrow: 201 rrow: 201)

????? leaf: 0x412082 4268162 (246: nrow: 240 rrow: 240)

????? leaf: 0x412083 4268163 (247: nrow: 226 rrow: 226)

????? leaf: 0x412084 4268164 (248: nrow: 211 rrow: 211)

?? branch: 0x41227b 4268667 (0: nrow: 245, level: 1)

????? leaf: 0x412085 4268165 (-1: nrow: 229 rrow: 229)

????? leaf: 0x412087 4268167 (0: nrow: 218 rrow: 218)

????? leaf: 0x412088 4268168 (1: nrow: 231 rrow: 231)

????? leaf: 0x412109 4268297 (2: nrow: 249 rrow: 249)

??? ??......

????? leaf: 0x412278 4268664 (241: nrow: 191 rrow: 191)

????? leaf: 0x412279 4268665 (242: nrow: 180 rrow: 180)

????? leaf: 0x41227a 4268666 (243: nrow: 56 rrow: 56)

----- end tree dump

?

?

2.6 解釋 treedump 輸出?

?????? branch 表示的是 branch block ,它后面跟了一個十六進制表示的DBA(data block address),以及用10進制表示的DBA

?????? DBA 之后表示在同一層次的相對位置(root 0開始,branch 以及leaf -1開始)?

?????? nrow? 表示塊中包含了多少條目(包括delete的條目)?

?????? rrow? 表示塊中包含的實際條目(不包括delete的條目)?

?????? level 表示從該blockleaf的深度(leaf沒有 level)?

?

2.6.1? branch: 0x4117c2 4265922 (0: nrow: 2, level: 2) 說明

?????? 這個 branch block level 2,也就是說 從這個branch block leaf block 的深度為2,根據前面的查詢,這個索引的Blevel2,所以這個branch其實是 root block. 其實根據 nrow:2 也可以看出來它是root block,因為nrow:2 說明它只包含了2個條目,那么這2個條目其實就是dump 文件中的其他2 branch block 的條目?

?

?????? 現在我來驗證一下 branch: 0x4117c2 4265922 (0: nrow: 2, level: 2) 是不是 root block , 我查詢這個 branch DBA

?

SYS@anqing2(rac2)> select dbms_utility.data_block_address_file('4265922') FILE_ID,? dbms_utility.data_block_address_block('4265922') BLOCK_ID from dual;

?

?? FILE_ID?? BLOCK_ID

---------- ----------

???????? 1????? 71618

?

Btree 索引的 root block總是segment header+1,所以我查詢該索引的段頭?

?

SYS@anqing2(rac2)> select header_file,header_block from dba_segments where segment_name='IDX_TE_OBJECT_NAME';?

?

HEADER_FILE HEADER_BLOCK

----------- ------------

????????? 1??????? 71617

?

?????? 那么現在已經證明了 branch: 0x4117c2 4265922 (0: nrow: 2, level: 2) root block, 其實 treedump第一個 branch block 就是 root block

?

?

2.6.2 ?branch: 0x412086 4268166 (-1: nrow: 250, level: 1)? 說明

?????? 這個branch DBA0x412086 (十六進制)4268166 (十進制) -1 表示它是與它在同一個深度的 branch block中的第一個 branch block?

?????? nrow: 250 :表示它有247 leaf block.

?????? level: 1 :表示 這個 branch block leaf block的深度為1?

?

2.6.3 leaf: 0x4117c3 4265923 (-1: nrow: 182 rrow: 182) ?說明

?????? leaf 表示它是一個 leaf block 0x4117c3 4265923 分別是這個 leaf block 十六進制/十進制的DBA.

?????? ?-1 表示它是 leaf block 中的第一個 block?

?????? nrow: 182 表示它一共有182條記錄

?????? rrow: 182 表示它實際有182條記錄?

?

?

2.7? branch block dump?

?????? 這里選擇dump branch: branch: 0x412086 4268166 (-1: nrow: 250, level: 1)

?

SYS@anqing2(rac2)> select dbms_utility.data_block_address_file('4268166') FILE_ID,? dbms_utility.data_block_address_block('4268166') BLOCK_ID from dual;?

?

?? FILE_ID?? BLOCK_ID

---------- ----------

???????? 1????? 73862

?

SYS@anqing2(rac2)> oradebug tracefile_name

/u01/app/oracle/admin/anqing/udump/anqing2_ora_3865.trc

-- 先清空一下

[oracle@rac2 ~]$ cat /dev/null > /u01/app/oracle/admin/anqing/udump/anqing2_ora_3865.trc

?

SYS@anqing2(rac2)> alter system dump datafile 1 block 73862;?

System altered.

?

2.7.1 部分 DUMP 文件?

[oracle@rac2 ~]$ cat /u01/app/oracle/admin/anqing/udump/anqing2_ora_3865.trc? ??????????

*** 2011-06-27 14:35:54.038

Start dump data blocks tsn: 0 file#: 1 minblk 73862 maxblk 73862

buffer tsn: 0 rdba: 0x00412086 (1/73862)

scn: 0x0000.004e24ec seq: 0x02 flg: 0x04 tail: 0x24ec0602

frmt: 0x02 chkval: 0x3371 type: 0x06=trans data

Hex dump of block: st=0, typ_found=1

Dump of memory from 0x0E707400 to 0x0E709400

E707400 0000A206 00412086 004E24EC 04020000? [..... A..$N.....]

......

E7093F0 00000000 00000000 00000000 24EC0602? [...............$]

Block header dump:? 0x00412086

?Object id on Block? Y

?seg/obj: 0xd5f1? csc: 0x00.4e24c9? 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.004e24c9

?

Branch block dump

=================

header address 242250820=0xe707444

kdxcolev 1

KDXCOLEV Flags = - - -

kdxcolok 0

kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y

kdxconco 2

kdxcosdc 0

kdxconro 249

kdxcofbo 526=0x20e

kdxcofeo 557=0x22d

kdxcoavs 31

kdxbrlmc 4265923=0x4117c3

kdxbrsno 0

kdxbrbksz 8056

kdxbr2urrc 0

?

row#0[8023] dba: 4265924=0x4117c4

col 0; len 24; (24):

?2f 31 30 64 65 32 32 63 36 5f 43 6c 61 73 73 54 79 70 65 49 6d 70 6c 32

col 1; len 3; (3):? 00 41 1b

row#1[7984] dba: 4265925=0x4117c5

col 0; len 30; (30):

?2f 31 31 64 35 30 39 31 32 5f 44 61 74 65 46 6f 72 6d 61 74 5a 6f 6e 65 44

?61 74 61 5f 7a

col 1; len 3; (3):? 00 41 1c

row#2[7973] dba: 4265926=0x4117c6

col 0; len 5; (5):? 2f 31 32 61 32

col 1; TERM

row#3[7931] dba: 4265927=0x4117c7

col 0; len 30; (30):

?2f 31 33 38 35 32 32 37 66 5f 4d 61 70 52 65 67 69 6f 6e 43 6f 6e 74 61 69

?6e 6d 65 6e 74

col 1; len 6; (6):? 00 41 18 d5 00 08

......

row#247[571] dba: 4268163=0x412083

col 0; len 6; (6):? 41 4c 4c 5f 45 56

col 1; TERM

row#248[557] dba: 4268164=0x412084

col 0; len 8; (8):? 41 4c 4c 5f 4d 50 5f 50

col 1; TERM

----- end of branch block dump -----

End dump data blocks tsn: 0 file#: 1 minblk 73862 maxblk 73862

[oracle@rac2 ~]$

?

?

2.7.2解釋部分dump輸出?

?

kdxcolev 1? --blockleaf block的深度(leaf block 0).這里branch block level 1 與前面查詢相吻合??

KDXCOLEV Flags = - - -?

kdxcolok 0? --表示是否有事務lock了這個branch block,如果有,有多少事務?

kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y?

kdxconco 2? --索引值條目. 這里表示有2個條目?

kdxcosdc 0? --這個block的結構被更改次數.這里0表示沒有更改?

kdxconro 249 --索引條目(不包含kdxbrlmc 指針)?

kdxcofbo 526=0x20e? --空閑空間的起始偏移量

kdxcofeo 557=0x22d? --空閑空間的末尾偏移量

kdxcoavs 31? --block中的空閑空間=kdxcofeo-kdxcofbo?

kdxbrlmc 4265923=0x4117c3 --如果index value小于row#0,指向該 block 的地址?

kdxbrsno 0?? --最后被更改的索引條目?

kdxbrbksz 8056 --塊中的可用空間?

kdxbr2urrc 0?

?

row#0[8023] dba: 4265924=0x4117c4 --row# 表示索引條目數,從0開始,緊接著就是十進制和十六進制的DBA,該DBA指向 leaf block?

?

col 0; len 24; (24): --列的行號,從0開始,緊接著的就是列的長度以及列的值,那么這個值稱之為separator key,這個separator key 可以區分真實的索引值,所以從這里我們也知道 branch block不會存儲完整的索引值,只要能區分就行?

?

?2f 31 30 64 65 32 32 63 36 5f 43 6c 61 73 73 54 79 70 65 49 6d 70 6c 32

col 1; len 3; (3):? 00 41 1b

?

?

2.8 ?leaf block DUMP?

?????? 這里選擇 row#247[571] dba: 4268163=0x412083, 因為它包含的索引鍵很少?

?

row#247[571] dba: 4268163=0x412083

col 0; len 6; (6):? 41 4c 4c 5f 45 56

col 1; TERM

?

dump 之前先看一下? row#247[571] 存儲的 ' 41 4c 4c 5f 45 56' 是什么索引鍵. 使用如下代碼轉換:

?

SQL> set serveroutput on

?

/* Formatted on 2011/6/27 16:53:27 (QP5 v5.163.1008.3004) */

DECLARE

?? n?? VARCHAR2 (2000);

BEGIN

?? DBMS_STATS.convert_raw_value ('41', n);

?? DBMS_OUTPUT.put_line (n);

?? DBMS_STATS.convert_raw_value ('4c', n);

?? DBMS_OUTPUT.put_line (n);

?? DBMS_STATS.convert_raw_value ('4c', n);

?? DBMS_OUTPUT.put_line (n);

?? DBMS_STATS.convert_raw_value ('5f', n);

?? DBMS_OUTPUT.put_line (n);

?? DBMS_STATS.convert_raw_value ('45', n);

?? DBMS_OUTPUT.put_line (n);

?? DBMS_STATS.convert_raw_value ('46', n);

?? DBMS_OUTPUT.put_line (n);

END;

?

這個鍵值代表:

A

L

L

_

E

F

?

-- 查看file_id block_id

SYS@anqing2(rac2)> select dbms_utility.data_block_address_file('4268163') FILE_ID,???? dbms_utility.data_block_address_block('4268163')? BLOCK_ID from dual;?

?

?? FILE_ID?? BLOCK_ID

---------- ----------

?????? ??1????? 73859

?

SYS@anqing2(rac2)> alter system dump datafile 1 block 73859;?

System altered.

?

SYS@anqing2(rac2)> oradebug tracefile_name

/u01/app/oracle/admin/anqing/udump/anqing2_ora_3865.trc

?

2.8.1 部分DUMP文件?

?

[oracle@rac2 ~]$ cat /u01/app/oracle/admin/anqing/udump/anqing2_ora_3865.trc

*** 2011-06-27 17:00:01.805

Start dump data blocks tsn: 0 file#: 1 minblk 73859 maxblk 73859

buffer tsn: 0 rdba: 0x00412083 (1/73859)

scn: 0x0000.004e24ec seq: 0x02 flg: 0x04 tail: 0x24ec0602

frmt: 0x02 chkval: 0xb42b type: 0x06=trans data

Hex dump of block: st=0, typ_found=1

Dump of memory from 0x0E707400 to 0x0E709400

E707400 0000A206 00412083 004E24EC 04020000? [..... A..$N.....]

......

E7093F0 00000000 00000000 00000000 24EC0602? [...............$]

Block header dump:? 0x00412083

?Object id on Block? Y

?seg/obj: 0xd5f1? csc: 0x00.4e24c9? itc: 2? flg: -? typ: 2 - INDEX

???? fsl: 0? fnx: 0x0 ver: 0x01

?

?Itl?????????? Xid????????????????? Uba???????? Flag? Lck??????? Scn/Fsc

0x01?? 0x0000.000.00000000? 0x00000000.0000.00? ----??? 0? fsc 0x0000.00000000

0x02?? 0xffff.000.00000000? 0x00000000.0000.00? C---??? 0? scn 0x0000.004e24c9

?

Leaf block dump

===============

header address 242250844=0xe70745c

kdxcolev 0

KDXCOLEV Flags = - - -

kdxcolok 0

kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y

kdxconco 2

kdxcosdc 0

kdxconro 226

kdxcofbo 488=0x1e8

kdxcofeo 1324=0x52c

kdxcoavs 836

kdxlespl 0

kdxlende 0

kdxlenxt 4268164=0x412084

kdxleprv 4268162=0x412082

kdxledsz 0

kdxlebksz 8032

row#0[7999] flag: ------, lock: 0, len=33

col 0; len 23; (23):

?41 4c 4c 5f 45 56 41 4c 55 41 54 49 4f 4e 5f 43 4f 4e 54 45 58 54 53

col 1; len 6; (6):? 00 41 1a 71 00 2a

row#1[7966] flag: ------, lock: 0, len=33

col 0; len 23; (23):

?41 4c 4c 5f 45 56 41 4c 55 41 54 49 4f 4e 5f 43 4f 4e 54 45 58 54 53

col 1; len 6; (6):? 00 41 1a 71 00 2b

row#2[7933] flag: ------, lock: 0, len=33

col 0; len 23; (23):

?41 4c 4c 5f 45 56 41 4c 55 41 54 49 4f 4e 5f 43 4f 4e 54 45 58 54 53

col 1; len 6; (6):? 00 43 eb 77 00 3d

......

row#224[1357] flag: ------, lock: 0, len=33

col 0; len 23; (23):

?41 4c 4c 5f 4d 50 5f 47 52 41 50 48 5f 57 4f 52 4b 53 50 41 43 45 53

col 1; len 6; (6):? 00 41 1a ad 00 18

row#225[1324] flag: ------, lock: 0, len=33

col 0; len 23; (23):

?41 4c 4c 5f 4d 50 5f 47 52 41 50 48 5f 57 4f 52 4b 53 50 41 43 45 53

col 1; len 6; (6):? 00 41 1a ad 00 19

----- end of leaf block dump -----

End dump data blocks tsn: 0 file#: 1 minblk 73859 maxblk 73859

[oracle@rac2 ~]$

?

?

2.8.2 解釋部分dump輸出

kdxcolev 0? --blockleaf block的深度(leaf block 0).?

KDXCOLEV Flags = - - -?

kdxcolok 0?? --表示是否有事務lock了這個branch block,如果有 有多少事務?

kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y?

kdxconco 2?? --索引值條目. 這里表示有2個條目?

kdxcosdc 0?? --這個block的結構被更改次數.這里0表示沒有更改?

kdxconro 226 ??--索引條目 ,這里有189個索引條目 它等于 row#225-row#0+1?

kdxcofbo 488=0x1e8? --空閑空間的起始偏移量?

kdxcofeo 1324=0x52c ?--空閑空間的末尾偏移量?

kdxcoavs 836??????? --block中的空閑空間=kdxcofeo-kdxcofbo?

kdxlespl 0?? --block split的時候沒有commit的記錄的大小(byte)?

kdxlende 0?? --被刪除的條目?

kdxlenxt 4268164=0x412084 --指向下一個 leaf block的指針(DBA)?

kdxleprv 4268162=0x412082 --指向上一個 leaf block的指針(DBA)?

kdxledsz 0?? --被刪除的空間?

kdxlebksz 8032 --可用空間?

?

?

row#0[7999] flag: ------, lock: 0, len=33

col 0; len 23; (23):

?41 4c 4c 5f 45 56 41 4c 55 41 54 49 4f 4e 5f 43 4f 4e 54 45 58 54 53

col 1; len 6; (6):? 00 41 1a 71 00 2a

?

row# 表示索引值的條目,從0開始? lock: 0 表示ITL中的鎖信息 0表示沒有被鎖 len=33 表示索引值長度?

col 表示列號,從0開始 那么接下來就是索引的鍵值 以及 rowid中后23位值。

?????? 即:col 0 是鍵值, col 1 rowid

?

下面我們來看一下row#0存儲的值是什么 ,先看col 0的鍵值:

?

SYS@anqing2(rac2)> declare n varchar2(2000);?

? 2? begin?

? 3? dbms_stats.convert_raw_value('414c4c5f4556414c554154494f4e5f434f4e5445585453',n);?

? 4? dbms_output.put_line(n);?

? 5? end;?

? 6? /?

ALL_EVALUATION_CONTEXTS

?

查看col1 rowid 的值:

ROWID一共用18位表示 :

?????? 最前6位表示 data object number?

?????? 之后后3位表示 datafile number?

?????? 之后后6位表示 datablock number?

?????? 最后3位表示 row number?

?

有關rowid 更多內容,參考Blog

?????? Oracle Rowid 介紹

?????? http://blog.csdn.net/tianlesoftware/archive/2009/12/16/5020718.aspx

?

SYS@anqing2(rac2)> select to_number('00411a71','xxxxxxxxxxxxxxxx') from dual; ?

TO_NUMBER('00411A71','XXXXXXXXXXXXXXXX')

----------------------------------------

????????????? 4266609?

?

?????? 這里的rowid其實是除去了 data object number的一部分而已。 col 16位中的前4位。

?

SYS@anqing2(rac2)> select dbms_utility.data_block_address_file('4266609') FILE_ID,dbms_utility.data_block_address_block('4266609') BLOCK_ID from dual;?

?

?? FILE_ID?? BLOCK_ID

---------- ----------

???????? 1????? 72305?

?

SYS@anqing2(rac2)> select dbms_rowid.rowid_relative_fno(rowid)file_id, dbms_rowid.rowid_block_number(rowid)block_id,dbms_rowid.rowid_row_number(rowid) row#? from te where object_name='ALL_EVALUATION_CONTEXTS';?

?

?? FILE_ID?? BLOCK_ID?????? ROW#

---------- ---------- ----------

???????? 1????? 72305?????? ??42

???????? 1????? 72305???????? 43

???????? 1???? 256887???????? 61

???????? 1???? 256887???????? 62?

?

?

根據這個還原的值我來查詢一下?

?

SYS@anqing2(rac2)> select owner,object_name,rowid from te where object_name='ALL_EVALUATION_CONTEXTS';?

?

OWNER????? OBJECT_NAME?????????????? ROWID

---------- ------------------------- ------------------

SYS??????? ALL_EVALUATION_CONTEXTS?? AAANXwAABAAARpxAAq

PUBLIC???? ALL_EVALUATION_CONTEXTS?? AAANXwAABAAARpxAAr

SYS??????? ALL_EVALUATION_CONTEXTS?? AAANXwAABAAA+t3AA9

PUBLIC???? ALL_EVALUATION_CONTEXTS?? AAANXwAABAAA+t3AA+

?

?

SYS@anqing2(rac2)> select owner,object_name,dump(rowid,16) from te where object_name='ALL_EVALUATION_CONTEXTS';?

?

OWNER????? OBJECT_NAME?????????????? DUMP(ROWID,16)

---------- ------------------------- -------------------------------------------

SYS????? ALL_EVALUATION_CONTEXTS?? Typ=69 Len=10: 0,0,d5,f0,0,41,1a,71,0,2a

PUBLIC???? ALL_EVALUATION_CONTEXTS?? Typ=69 Len=10: 0,0,d5,f0,0,41,1a,71,0,2b

SYS??????? ALL_EVALUATION_CONTEXTS?? Typ=69 Len=10: 0,0,d5,f0,0,43,eb,77,0,3d

PUBLIC???? ALL_EVALUATION_CONTEXTS?? Typ=69 Len=10: 0,0,d5,f0,0,43,eb,77,0,3e?

?

?

在看一下,在2.8節開始的branch block 信息:

row#247[571] dba: 4268163=0x412083

col 0; len 6; (6):? 41 4c 4c 5f 45 56

col 1; TERM

?

其中col 0,我們轉換之后是:ALL_EF,由此可見,col 0 是真正的索引鍵的前綴。

?

它是每個具體鍵值的前一部分,即col0 的一部分。 如:

?

row#0[7999] flag: ------, lock: 0, len=33

col 0; len 23; (23):

?41 4c 4c 5f 45 56 41 4c 55 41 54 49 4f 4e 5f 43 4f 4e 54 45 58 54 53

col 1; len 6; (6):? 00 41 1a 71 00 2a

?

?????? Oracle Branch block中只記錄 索引鍵值的前綴,而不是所有值,是因為這樣可以節約空間,從而能夠存儲更多的 索引條目。

?????? 同時,我們也能理解了為什么 查詢使用 like '%xxx' 這種方法不會走Btree 索引,因為Branch block 存儲的是前綴. ?

?

?

?

說明:

?????? 根據robinson blog,重新做的測試,原文鏈接如下:

?????? http://blog.csdn.net/robinson1988/archive/2011/01/04/6116276.aspx

?

?

?

?

?

-------------------------------------------------------------------------------------------------------

Blog http://blog.csdn.net/tianlesoftware

Email: dvd.dba@gmail.com

DBA1 群:62697716(滿);?? DBA2 群:62697977(滿)?? DBA3 群:62697850(滿)??

DBA 超級群:63306533(滿);? DBA4 群: 83829929? DBA5群: 142216823???

DBA6 群:158654907? 聊天 群:40132017?? 聊天2群:69087192

--加群需要在備注說明Oracle表空間和數據文件的關系,否則拒絕申請

?

轉載于:https://www.cnblogs.com/hibernate315/archive/2011/06/27/2399002.html

總結

以上是生活随笔為你收集整理的Oracle B-Tree Index 原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。