oracle index block splits
index是一个逻辑有顺序的结构并非物理存储block上排序,它总是可以把每个键值有顺序的逻辑排放,索引的高度总是平衡的,并且index leaf block就像一个双向链表,在index leaf block上会记录前一块的地址和后一块的地址,这样在index range scan 是就可以很方便的横向扫描,并且对于索引列的update 操作,其实是对Key values的deleting old value and insering the new values。
下面我举个例子来说明b-tree index 的分裂情况
比如下面这个结构
----- begin tree dump branch: 0x1000213 16777747 (0: nrow: 2, level: 1) leaf: 0x1000214 16777748 (-1: nrow: 540 rrow: 540) leaf: 0x1000215 16777749 (0: nrow: 460 rrow: 460) ----- end tree dump
一个分支下有两个叶子块,总共是1000个值,因为insert的是1到1000,所以第一块上的值就是1到540,这个可以dump block转储出来确认
那如果这时再insert值为 500 到520的值进去,又回如何呢?
这样就会产生一种index block split 50-50,这也是默认的分裂方式,分裂后的节点分布如下
----- begin tree dump *** 2012-05-01 05:32:40.346 branch: 0x1000213 16777747 (0: nrow: 3, level: 1) leaf: 0x1000214 16777748 (-1: nrow: 279 rrow: 279) leaf: 0x1000217 16777751 (0: nrow: 282 rrow: 282) leaf: 0x1000215 16777749 (1: nrow: 460 rrow: 460) ----- end tree dump
如果原来块上没有可用空间,就会从原来的块中拿出50% 的key value,和新加入值组成新的块,同时还会更新第三个块的指针,因为此块还是按key的顺序出现了插队现象(加塞儿)
同时如果观查统计信息会发现产生了leaf node splits
anbob@sql>select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.statistic# and b.name like '%split%' and sid in(select sid from v$mystat where rownum=1); NAME VALUE ---------------------------------------------------------------- ---------- leaf node splits 1 leaf node 90-10 splits 0 branch node splits 0 root node splits 0 queue splits 0
再看另外一种情况,如果insert 大于当前的最大值呢?比如1500-1720,也就是向右侧插入新数据,如果第三个index leaf block放不下呢?
这样就会产生另一种leaf node 90-10 splits,这是在10g中才起作用的
NAME VALUE ---------------------------------------------------------------- ---------- leaf node splits 1 leaf node 90-10 splits 1 branch node splits 0 root node splits 0 queue splits 0
结构变成了下面的情况
----- begin tree dump branch: 0x1000213 16777747 (0: nrow: 4, level: 1) leaf: 0x1000214 16777748 (-1: nrow: 279 rrow: 279) leaf: 0x1000217 16777751 (0: nrow: 282 rrow: 282) leaf: 0x1000215 16777749 (1: nrow: 533 rrow: 533) leaf: 0x1000216 16777750 (2: nrow: 148 rrow: 148) ----- end tree dump
不过注意leaf node splits 包含leaf node 90-10 splits,leaf node splits是50-50和90-10的总和。
如果在索引列发生了delete会怎样呢?
oracle从来不会把新插入的值放到以前分配好的块上,即使那个块上有90%的可用空间,新增加的值总是去b-tree结构的尾部分配新块,如果以前leaf block上的所有Key都标志为deleted,那么这个块就可以再次重复利用,分配给下一个leaf block,所以b-tree 物理块并不是有序的。
上一篇: index block dump
对不起,这篇文章暂时关闭评论。