`
liulanghan110
  • 浏览: 1064798 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

反向键索引的原理和用途

阅读更多

我们知道Oracle会自动为表的主键列建立索引,这个默认的索引是普通的B-Tree索引。对于主键值是按

 

顺序(递增或递减)加入的情况,默认的B-Tree索引并不理想。这是因为如果索引列的值具有严格顺序

 

时,随着数据行的插入,索引树的层级增长很快。搜索索引发生的I/O读写次数和索引树的层级数成正

 

比,也就是说,一棵具有5个层级的B -Tree索引,在最终读取到索引数据时最多可能发生多达5次I/O操

 

作。因而,减少索引的层级数是索引性能调整的一个重要方法。

 

  如果索引列的数据以严格的有序的方式插入,那么B-Tree索引树将变成一棵不对称的"歪树",如图

 

1所示:

 

 

       而如果索引列的数据以随机值的方式插入,我们将得到一棵趋向对称的索引树,如图 2所示:

 

 

 

 

比较图 1和图 2,在图 1中搜索到A块需要进行5次I/O操作,而图2仅需要3次I/O操作。

 

  既然索引列数据从序列中获取,其有序性无法规避,但在建立索引时,Oracle允许对索引列的值进

 

行反向,即预先对列值进行比特位的反向,如 1000,10001,10011,10111,1100经过反向后的值将是

 

0001,1001,1101,0011。显然经过位反向处理的有序数据变得比较随机了,这样所得到的索引树就比较

 

对称,从而提高表的查询性能。

 

初看上面的解释,觉得写的很对,可是却忘记了索引的结构是一个平衡的树,即根节点到每一个叶子节点的距离相等。所以不存在上面的有序的值使索引层级增大的问题。实际上反转索引时为了解决热块冲突的问题。比如有ID 为1,2,3,4,5,都在索引块的BLOCK A中。当用id =1 访问时,访问的是BLOCK A。当用id =2 访问时,访问的是BLOCK A。这样就会导致索引出现热块(关于热快请参考http://zhuyuehua.iteye.com/blog/1874708)。如果反转后存放,就可能1在BLOCK A,2在BLOCK B

访问的是BLOCK A。当用id =1 访问时,访问的是BLOCK A。当用id =2 访问时,访问的是BLOCK B。

这样就解决了索引的热快问题。

 

  反向键索引也有它局限性:如果在WHERE语句中,需要对索引列的值进行范围性的搜索,如

 

BETWEEN、<、>等,其反向键索引无法使用,此时,Oracle将执行全表扫描;只有对反向键索引列进

 

行 <>和 = 的比较操作时,其反向键索引才会得到使用。

 

测试 下反向索引:

 

create index IDX_OH_CODE on TEST ( code );

 

select * from TEST where code = '111';

 

select * from TEST where code < '111';

 

create index IDX_OH_CODE on TEST ( code ) reverse;

 

select * from TEST where code = '111';

 

select * from TEST where code < '111';

 

可以发现当普通索引用code < '111'是索引范围扫描时,反转索引不是。

  • 大小: 5.2 KB
  • 大小: 4.2 KB
分享到:
评论
1 楼 willxue 2017-03-24  
看了半天 前面说的是错的?。。。

相关推荐

Global site tag (gtag.js) - Google Analytics