关于Oracle btree索引初步认识

今天研究下Oracle的btree索引,通过这篇文章你会了解到,Oracle btree索引都有哪几种类型、Oracle btree索引的实现原理,Oracle通过btree索引检索数据的过程、以及b*tree索引的限制,并且Oracle和mysql的btree索引的区别。

一:Oracle中 btree索引的子类型:

b*tree索引是Oracle乃至大部分其他数据库中最常用的索引,b*tree的构造类似于二叉树,但是这里的“B”不代表二叉(binary),而代表平衡(balanced),b*tree索引有以下子类型:

1)索引组织表(index organized table): 索引组织表以B*树结构存储,我们知道Oracle默认的表是是堆表,堆表是以一种无组织的方式存储的(只要有可用的空间,就可以放数据),而IOT与之不同,IOT中的数据按着主键的顺序存储和排序的,对于应用来说,IOT表现得和常规的堆表并无区别,需要使用sql来正确的来访问IOT, IOT对信息获取、空间系统和OLAP应用最为有用,简单的概述起来:索引组织表----索引就是数据,数据就是索引,因为数据就是按着B*树结构存储的。

2)b*tree聚簇索引(B*tree cluster index):基于聚簇键(如 age=27),在传统的btree索引中,键都指向一行,而B*树聚簇不同,一个聚簇键会指向一个块,其中包含与这个聚簇键相关的多行,

3)降序索引:允许数据在索引结构中按“从大到小”的顺序(降序)排序,而不是“从小到大的顺序(升序)排序,当你查询数据的时候,最后排序oder by A desc,B asc的时候,创建降序索引就能避免做昂贵的排序(sort order by )操作,如下语句创建:

SQL>create index idex_name on table_name(A desc,B asc);

4)反向键索引(reverse key index):这也是 btree索引,只不过键的字节会“反转”,利用反向键索引,如果索引中填充的是递增的值,索引条目在索引中可以得到更均匀的分布;主要是解决“右侧”索引叶子块的竞争,比如在一个Oracle RAC的环境中,某些列用一个序列值或者时间戳填充,这些列上建立索引就属于“右侧”索引,也就是数据分布的相对比较集中。使用反向索引最大的优点莫过于降低索引叶子块的争用,减少索引热点块,提高系统性能。

1.反向索引应用场合

1)发现索引叶块成为热点块时使用

通常,使用数据时(常见于批量插入操作)都比较集中在一个连续的数据范围内,那么在使用正常的索引时就很容易发生索引叶子块过热的现象,严重时将会导致系统性能下降。

2)在RAC环境中使用

当RAC环境中几个节点访问数据的特点是集中和密集,索引热点块发生的几率就会很高。如果系统对范围检索要求不是很高的情况下可以考虑使用反向索引技术来提高系统的性能。因此该技术多见于RAC环境,它可以显著的降低索引块的争用。

2.使用反向索引的缺点

由于反向索引结构自身的特点,如果系统中经常使用范围扫描进行读取数据的话(例如在where子句中使用“between and”语句或比较运算符“>”“<”等),那么反向索引将不适用,因为此时会出现大量的全表扫描的现象,反而会降低系统的性能。

二:Oracle中BTree索引的实现原理:

一个经典的BTree索引的结构如下图:

关于Oracle btree索引初步认识

每个节点占用一个磁盘块的磁盘空间,一个节点上有n个升序排序的关键字和(n+1)个指向子树根节点的指针(上图中关键字为51,101,151.。。。。,然后0到50 对应一个指针,51到100对应一个指针),这个指针存储的是子节点所在磁盘块的地址(注意这里的n是创建索引的时候,根据数据量计算出来的,如果数据量太大了,三层的可能就满足不了,就需要四层的B+tree),然后n个关键字划分成(n+1)个范围域,然后每个范围域对应一个指针,来指向子节点,子节点又从新根据关键字再次划分,然后指针指向叶子节点,并且所有的叶子节点都在树的同一层上,这说明所有的从索引根节点到叶子节点的遍历都会访问同样数目的块,也就是说会执行同样数目的I/O,换言之索引是高度平衡的,

上图就是 0...50对应一个指针,指向一个子节点;51...100对应一个指针,指向另一个子节点,然后子节点又根据关键字划分区域,并由指针指向叶子结点,值得注意的是Oracle B*树索引存数据的是叶子节点(或者叫叶子块);存的是索引键值(或者叫索引的列值)和一个rowid(指向所索引的行的一个指针或者说叫物理位置),然后如上图所示,叶子节点之间有双向链表,就是为了提高索引范围扫描的效率,因为索引值的列值是有序的,找到了起始值后,直接就可以有序的去相邻中找到下一个值,例如 where id between 10 and 20 ,Oracle 发现第一个最小键值大于或等于10的索引叶子块,然后水平地遍历叶子节点链表,直到最后一个大于20的值;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/3952f22786d8e32993895cee0e7e512e.html