b-tree结构

B-Tree Index的结构浅探

PHP code:

B
-Tree Index的结构浅探

1 准备测试环境 ads3
+10g 10.1.0.2

SQL
create table t1(id number,name varchar2(32));                                                       

Table created.

SQLinsert into t1 select rownum,object_name as name from dba_objects;

10666 rows created.

SQLcreate index idx_t1_id on t1(id);

Index created.

SQLcreate index idx_t1_name on t1(name);

Index created.

SQLcreate index idx_t1_id_name on t1(id,name);

Index created.

2 数值字段上的索引

SQL
analyze index idx_t1_id validate structure;

Index analyzed.

Elapsed00:00:00.04

SQL
exec print_table('select * from index_stats');

HEIGHT                        2

BLOCKS                        
32

NAME                          
IDX_T1_ID

PARTITION_NAME                
:

LF_ROWS                       10666

LF_BLKS                       
23

LF_ROWS_LEN                   
160451

LF_BLK_LEN                    
7996

BR_ROWS                       
22

BR_BLKS                       
1

BR_ROWS_LEN                   
244

BR_BLK_LEN                    
8028

DEL_LF_ROWS                   
0

DEL_LF_ROWS_LEN               
0

DISTINCT_KEYS                 
10666

MOST_REPEATED_KEY             
1

BTREE_SPACE                   
191936

USED_SPACE                    
160695

PCT_USED                      
84

ROWS_PER_KEY                  
1

BLKS_GETS_PER_ACCESS          
3

PRE_ROWS                      
0

PRE_ROWS_LEN                  
0

OPT_CMPR_COUNT                
0

OPT_CMPR_PCTSAVE              
0

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

SQLselect file_id,extent_id,block_id,blocks 

from dba_extents where segment_name
='IDX_T1_ID';



   
FILE_ID  EXTENT_ID   BLOCK_ID     BLOCKS

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

         
5          0        417          8

         5          1        425          8

         5          2        433          8

         5          3        441          8

SQL
alter system dump datafile 5 block min 417 block max 424;



System altered.



SQLselect data_object_id from dba_objects where object_name ='IDX_T1_ID';



DATA_OBJECT_ID

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

         
12905

SQL
select file#,block# from sys.ind$ where dataobj#=12905;



     
FILE#     BLOCK#

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

         
5        419



通过dump的文件可知

block
# 417 block  : FIRST LEVEL BITMAP BLOCK

block# 418 block  : SECOND LEVEL BITMAP BLOCK

block# 419 block  : PAGETABLE SEGMENT HEADER



现在可以看看一第个branch block的内容......

buffer tsn7 rdba0x014001a4 (5/420)

scn0x0000.003c04dd seq0x01 flg0x04 tail0x04dd0601

frmt
0x02 chkval0xe5d9 type0x06=trans data

Block header dump
:  0x014001a4

 Object id on Block
Y

 seg
/obj0x3269  csc0x00.3c04d2  itc1  flgE  typ

     brn
0  bdba0x14001a1 ver0x01 opc0

     inc
0  exflg0

 

 Itl           Xid                  Uba         Flag  Lck        Scn
/Fsc

0x01   0xffff.000.00000000  0x00000000.0000.00  C
---    0  scn 0x0000.003c04d2

 





Branch block dump

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

header address 196782668=0xbbaaa4c

kdxcolev 1

KDXCOLEV Flags 
= - - -

kdxcolok 0

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

kdxconco 2

kdxcosdc 0

kdxconro 22

kdxcofbo 72
=0x48

kdxcofeo 7856
=0x1eb0

kdxcoavs 7784

kdxbrlmc 20971941
=0x14001a5  这个是第一个leaf block,除了kdxbrlmc记录的leaf block外

kdxbrsno 0                   下面列表中共列了22个leaf block
(row#0-row#21),如果id=8

kdxbrbksz 8056               的查询,oracle判断小于486,就会去遍历第1个leaf block kdxbr2urrc 0                  0x14001a5块。

row
#0[8047] dba: 20971942=0x14001a6 这个是第二个leaf block

col 0len 3; (3):  c2 05 57  => 486  (后面附有逆向运算的函数)   

col 1TERM

row
#1[8038] dba: 20971943=0x14001a7

col 0len 3; (3):  c2 0a 42  => 965

col 1
TERM

row
#2[8029] dba: 20971944=0x14001a8

col 0len 3; (3):  c2 0f 2d

col 1
TERM

row
#3[8020] dba: 20971945=0x14001a9

col 0len 3; (3):  c2 14 18

col 1
TERM

row
#4[8011] dba: 20971946=0x14001aa

col 0len 3; (3):  c2 19 03

col 1
TERM

row
#5[8002] dba: 20971947=0x14001ab

col 0len 3; (3):  c2 1d 51

col 1
TERM

row
#6[7993] dba: 20971948=0x14001ac

col 0len 3; (3):  c2 22 3c

col 1
TERM

row
#7[7984] dba: 20971949=0x14001ad

col 0len 3; (3):  c2 27 27

col 1
TERM

row
#8[7975] dba: 20971950=0x14001ae

col 0len 3; (3):  c2 2c 12

col 1
TERM

row
#9[7966] dba: 20971951=0x14001af

col 0len 3; (3):  c2 30 60

col 1
TERM

row
#10[7957] dba: 20971952=0x14001b0

col 0len 3; (3):  c2 35 4b

col 1
TERM

row
#11[7948] dba: 20971954=0x14001b2

col 0len 3; (3):  c2 3a 36

col 1
TERM

row
#12[7939] dba: 20971955=0x14001b3

col 0len 3; (3):  c2 3f 21

col 1
TERM

row
#13[7930] dba: 20971956=0x14001b4

col 0len 3; (3):  c2 44 0c

col 1
TERM

row
#14[7921] dba: 20971957=0x14001b5

col 0len 3; (3):  c2 48 5a

col 1
TERM

row
#15[7912] dba: 20971958=0x14001b6

col 0len 3; (3):  c2 4d 45

col 1
TERM

row
#16[7903] dba: 20971959=0x14001b7

col 0len 3; (3):  c2 52 30

col 1
TERM

row
#17[7894] dba: 20971960=0x14001b8

col 0len 3; (3):  c2 57 1b

col 1
TERM

row
#18[7885] dba: 20971961=0x14001b9

col 0len 3; (3):  c2 5c 06

col 1
TERM

row
#19[7876] dba: 20971962=0x14001ba

col 0len 3; (3):  c2 60 54

col 1
TERM

row
#20[7866] dba: 20971963=0x14001bb

col 0len 4; (4):  c3 02 01 3b

col 1
TERM

row
#21[7856] dba: 20971964=0x14001bc

col 0len 4; (4):  c3 02 06 08

col 1
TERM

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



oracle数据存储方式

<a href="http://www.itpub.net/211094.html" target="_blank">http://www.itpub.net/211094.html



关于求branch block中索引项最小值的函数:

create 
or replace function uf_dec(v_hex in varchar2)

return 
number

as

 
v_num varchar2(99);

 
v_lef varchar2(99);

 
v_str char(2);

 
v_dec number;

 
v_len number;

 
v_ins number;

begin

 v_lef 
:= v_hex;

 
v_str := trim(substr(v_lef,1,3));

 
v_len := length(v_str);



 while 
v_len 0 loop

    select to_number
(v_str,'xx'into v_dec from dual;

    if 
v_num is null then 

      v_num 
:= v_num || v_dec;

    else

      
v_num := v_num ||','||v_dec;

    
end if;      

    
v_lef := substr(v_lef,4);

    
v_str := trim(substr(v_lef,1,3));

    
v_len := length(v_str);

 
end loop;



 for 
i in 0 .. 1000000 loop

  select instr
(dump(i),v_numinto v_ins from dual

  if 
v_ins 0 then

      
return i;

      exit;

    
end if;

 
end loop;

end;



示例:

SQL
select uf_dec('&input_hex'from dual;

Enter value for input_hexc2 05 57

old   1
select uf_dec('&input_hex'from dual

new   1select uf_dec('c2 05 57'from dual

UF_DEC
('C20557')

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

486

    本例中idx_t1_id索引中
,共4个extent,共32个block,

1个branch block,23个leaf block,通过dump这32个block可知,

每个索引段的前3个block是metadata block,第4个block是branch block,其它的block是leaf block。在assm类型的表空间中,

segment的extent是按64k,1m,8m这样的算法增长的,当65k的增长到148个extent之后,就开始增长1m的extent,

当1m的增长够420之后,

就开始分配8m的extent,这样会避开大segment分配过多的extent。

    

SQL
select count(*) as totals,blocks 

from dba_extents where segment_name
='RESELLER_LOG' group by blocks;

    
TOTALS     BLOCKS

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

       
148          8

       420        128

        12       1024



<font color="red">

该索引IDX_T1_ID的branch block的中的大致内容:

<
486         block addr:0x14001a5 file_id 5 block_id 421

row
# 0     <965         block addr:0x14001a6 file_id 5 block_id 422

row# 1     <1444        block addr:0x14001a6 file_id 5 block_id 422

......

row#20     
row#21     >=10507     block addr:0x14001bc file_id 5 block_id 444

[/color]



SQLselect to_number('01bc','xxxx'from dual;



TO_NUMBER('01BC','XXXX')

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

                     
444


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7301064/viewspace-446887/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/7301064/viewspace-446887/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值