?B*树索引就是我们说的“传统”索引,这是数据库中最常用的一类索引结构。其实现与二叉查找树类似,目标是减少oracle查找数据的时间。如果在一个数字列上有一个索引,那么理论上结构应该是这样的:
? ? ? ??这个树最底层是叶子节点,包含索引键以及一个rowid(指向索引行)。叶子节点上面的称为分支块,用于在结构中实现导航。例如:想在索引中找到值42,从树顶开始查找,进入左分支,查找这个块,发现需要找的数据在“42...50”的叶子节点中。
? ? ? ? 另外,叶子节点之间是双向链表结构。也就是查找区间数据很容易,比如这样的条件,where x between 20 and 300。oracle只要刚开始找到大于或等于20的记录所在的叶子节点,接着往下扫描,找到大于或者等于300的块。这期间可能会跨叶子节点扫描,由于叶子节点之间是双向链表,故很容易实现跨叶子节点扫描。
? ? ? ?B*树有一个特点:所有的叶子节点都在同一层,也就是无论你查找哪一条数据,需要执行的I/O数据是一样的。一般的B*树都是2或者3层。无论这个表有多少行数据,这样查找一条数据只需要2,3个I/O操作。
?
? ? ? 索引键压缩
? ? ? 假如一个表中,需要三列才能确认一行。那么我们在这个表示建立索引需要建立在这三列上。那么索引块的结构有可能是这样的,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ?我们会发现,第一列和第二列有很多值是重复的。其实这个时候可以进行压缩,对于重复的值,只保存一份。比如:
?
- <SPAN?style="FONT-SIZE:?x-small">drop?index?t_idx; ??
- create?index?t_idx?on??
- t(owner,object_type,object_name) ??
- compress?&2;</SPAN>??
drop index t_idx;
create index t_idx on
t(owner,object_type,object_name)
compress &2;
?? ? ? compress&2表示压缩两列,这样能节省空间,但是会增加寻找的难度。也就是说,如果现在已经占用了大量的cpu时间,那么创建索引以压缩的方式,会使情况更糟糕。如果目前只是I/O操作比较多,那么压缩索引能加快处理速度,因为压缩之后的索引空间更少,那么块缓冲区应该能存放更多的索引块,块的命中率会提高。
?
? ? ? 反向键索引
? ? ? 假如我们建立的所有是在一个递增的列上,从上面的图1索引结构图,可以看出,相邻的值保存在同一索引块上。那么我们批量递增插入数据的时候,就会引起索引块的竞争。但是如果我们把索引值反转之后,原先相邻的值,就会相差很远,这样就降低了索引块的竞争。
? ? ? 反向索引有一个缺点,无法进行区间扫描。因为索引值已经反转,索引值相邻的值都是反转之后相邻的值,实际值其实相差很远,区间扫描无法进行。
? ? ? 那么,假设我们需要一个表,有一个主键是递增的,而且今后也不会在这个主键上进行区间扫描。但是有大批量的插入,这个时候就适合建立一个反向键索引。
?
? ? ? B*树使用情况
? ? ? 什么时候应该使用B*树索引,什么时候又不行呢?主要看两点:
? ? ? 1. 当需要通过索引访问表中很少一部分数据的时候,可以建立B*树索引。
? ? ? 2. 即使需要访问表中多行,但是能只访问索引解决,也可以建立B*树索引。比如select count(*) from ...。
?
? ? ? 为什么只有访问少量数据的时候,才能使用B*树索引呢,举一例子:
? ? ??假