Oracle索引内部结构研究

1. 创建一个块大小为2KB的表空间

create tablespace tbs_2k datafile 'C:\APP\ADMINISTRATOR\ORADATA\HXL11G\hxl01.DBF' size 128m blocksize 2k;
如果报错执行如下语句:

alter system set db_2k_cache_size=50 scope=both;

2. 创建测试表

drop table index_test;

create table index_test(id char(150)) tablespace tbs_2k;

create index idx_test on index_test(id) tablespace tbs_2k;

3. 查看空索引内部结构

select object_id from user_objects where object_name='IDX_TEST';

alter session set events 'immediate trace name treedump level 69907';--69907为上一个SQL查出来的结果

4. 在oracle日志记录的地方一般是在udump文件夹下面,找到一个修改时间最新的文件。我机器的文件是 orcl_ora_5576.trc,如下所示

Oracle索引内部结构研究_第1张图片



5. 打开这个日志文件我们可以看到如下内容

----- begin tree dump
leaf: 0x48000c5 75497669 (0: nrow: 0 rrow: 0)
----- end tree dump

left代表叶子节点,0: nrow: 0 rrow: 0:0代表层级,nrow表示当前节点中所含有的索引条目的数量,rrow表示有效的索引条目。nrow-rrow表示删除的索引条目(无效条目)


6. 往表里面插入10行数据,同时查看索引结构

begin
for i in 1..10 loop
insert into index_test values (rpad(to_char(i*2),150,'a'));
end loop;
end;
/

commit;

alter session set events 'immediate trace name treedump level 69907';
打开最新的那个日志文件,可以看到如下内容

----- begin tree dump
leaf: 0x48000c5 75497669 (0: nrow: 10 rrow: 10)
----- end tree dump

nrow和rrow都变成了10,意思是这一个块存放了10个有效的索引条目


7. 查看索引块的内部结构

select dbms_utility.data_block_address_file(75497669),
dbms_utility.data_block_address_block(75497669) from dual;--75497669为索引块地址

alter system dump datafile 18 block 197;--18,197为上一步查询的结果
打开最新日志文件我们会看到如下内容

Leaf block dump
===============
header address 135955556=0x81a8464
kdxcolev 0 --索引层级号
KDXCOLEV Flags = - - -
kdxcolok 0 --该索引上是否正在发生修改块结构的事务
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y  --内部操作代码
kdxconco 2 --索引条目中列的数量
kdxcosdc 0 --索引结构发生变化的数量,当你修改表里的某个索引键值时,该值增加
kdxconro 10 --表示当前索引节点中索引条目的数量
kdxcofbo 56=0x38 --当前索引节点中可用空间的起始点相对当前块的位移量
kdxcofeo 282=0x11a --当前索引节点中可用空间的最尾端的相对当前块的位移量
kdxcoavs 226 --当前索引块中的可用空间总量,也就是用kdxcofeo减去kdxcofbo得到的
kdxlespl 0 --当叶子节点被拆分时未提交的事务数量
kdxlende 0 --表示被删除的索引条目的数量
kdxlenxt 0=0x0 --表示当前叶子节点的下一个叶子节点的地址
kdxleprv 0=0x0 --表示当前叶子节点的上一个叶子节点的地址
kdxledsz 0 --表示可用空间
kdxlebksz 1892 --可用数据块的空间大小,2KB应该是2048,应该是预留了一些空间
row#0[1087] flag: ------, lock: 2, len=161  --其中flag表示标记,比如删除标记等;而lock表示锁定信息,len表示长度
col 0; len 150; (150):  --col 0表示索引键值
 31 30 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
col 1; len 6; (6):  04 80 00 af 00 04 --col 1表示ROWID


8.继续插入一行,查看kdxcoavs(可用空间)

insert into index_test values(rpad(to_char(11*2),150,'a'));

alter system dump datafile 18 block 197;
日志片段如下

Leaf block dump
===============
header address 135955556=0x81a8464
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 11
kdxcofbo 58=0x3a
kdxcofeo 121=0x79
kdxcoavs 63 --可用空间由226编程了63,一个索引条目226-63=163
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 1892

9. 继续插入一行,这个时候索引块空间不够,会产生裂变。这个索引块变成了根节点,下面又挂了两个子节点,然后将索引条目进行拆分,一边放一点

insert into index_test values(rpad(to_char(12*2),150,'a'));

alter system dump datafile 18 block 197;

查看日志片段:

Branch block dump
=================
header address 135955532=0x81a844c
kdxcolev 1
KDXCOLEV Flags = - - -
kdxcolok 1
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 1
kdxconro 1
kdxcofbo 30=0x1e
kdxcofeo 1909=0x775
kdxcoavs 1879
kdxbrlmc 75497687=0x48000d7 --第一个叶子节点位置
kdxbrsno 0
kdxbrbksz 1916 
kdxbr2urrc 0
row#0[1909] dba: 75497670=0x48000c6 --第二个叶子节点位置
col 0; len 1; (1):  34
col 1; TERM


10. 查看第一个叶子块内部结构

select dbms_utility.data_block_address_file(75497687),
dbms_utility.data_block_address_block(75497687) from dual; --75497687第一个叶子块地址

alter system dump datafile 18 block 215; --上一步查询结果
日志片段如下:

Leaf block dump
===============
header address 135955556=0x81a8464
kdxcolev 0 --0层
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2 --两列
kdxcosdc 1
kdxconro 9 --9行索引条目,说明插入12行索引条目的时候裂变成2个叶子块,该叶子块存放9个索引条目,另一个叶子块存放3个索引条目
kdxcofbo 54=0x36
kdxcofeo 282=0x11a
kdxcoavs 389
kdxlespl 0
kdxlende 0
kdxlenxt 75497670=0x48000c6 --下一个叶子块地址
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 1892
row#0[443] flag: ----S-, lock: 2, len=161
col 0; len 150; (150): 
 31 30 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
col 1; len 6; (6):  04 80 00 af 00 04

11. 查看第二个叶子块内部结构

select dbms_utility.data_block_address_file(75497670),
dbms_utility.data_block_address_block(75497670) from dual;--75497670为叶子块地址

alter system dump datafile 18 block 198;--18,198上一步查询结果
查看日志片段

Leaf block dump
===============
header address 135955556=0x81a8464
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 1
kdxcoopc 0x87: opcode=7: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 1
kdxconro 3 --验证了上一步,这里面存放了3个索引条目
kdxcofbo 42=0x2a
kdxcofeo 1409=0x581
kdxcoavs 1367
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 75497687=0x48000d7 --上一个索引块地址
kdxledsz 0
kdxlebksz 1892
row#0[1409] flag: ----S-, lock: 2, len=161
col 0; len 150; (150): 
 34 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
col 1; len 6; (6):  04 80 00 af 00 01



你可能感兴趣的:(oracle,oracle,索引)