Oracle复合B*tree索引branch block内是否包含非先导列键值?

好久不碰数据库底层细节的东西,前几天,一个小家伙跑来找我,非要说复合b*tree index branch block中只包含先导列键值信息,并不包含非先导列键值信息,而且还dump了branch block,用以证明他的说法,从常理和SQL的语句执行信息就可以知道,他的说法是有问题的,但如何证明这一点呢?为了证明这点,也麻烦一次,玩玩多年不碰的dump。下面是他证明自己观点的两个dump结果(一个为单键索引,另一个是复合索引):

下面是本人的测试过程和结果:

create table t1(c1 int,c2 int,c3 int,c4 char(2000),c5 char(2000));

create index t1_idx1 on t1(c1,c2,c3,c4,c5);

begin

for i in 1..1000 loop
insert into t1 values(0,0,i,'aa','aa');
end loop;
end;
/

begin
for i in 1001..2000 loop
insert into t1 values(0,i,i,'bb','bb');
end loop;
end;
/

select segment_name,file_id,block_id 
  from dba_extents 
 where segment_name='T1_IDX1'
   and extent_id=0;


alter system dump datafile 4 block 195;

trc文件内容:

由此可见,复合b*tree index branch block中,有时不包含非先导列键值,但有时包含。那么,什么情况下包含,什么情况下不包含呢?实验结果为,当先导列键值的选择性足够好时,就无需包含非先导列的键值,不然,也是浪费branck block宝贵的空间;只有当先导列的键值选择性不足够好,必须结合非先导列的键值才能定位到下一级block时,才需要包含非先导列的键值,该测试过程此处略去,感兴趣的同学可以按照这个思路自己测试。

原文地址:https://www.cnblogs.com/lhdz_bj/p/8778377.html