Oracle 建立反向键索引

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Oracle 建立反向键索引

在Oracle中,系统会自动为表的主键列建立索引,这个默认的索引是普通的B树索引。通常,用户会希望表的主键是一个自动增长的序列编号,这样的列就是所谓的单调递增序列编号列。当在这种顺序递增的列上建立普通的B树索引时,如果果表的数据量非常庞大,将导致索引数据分布不均。为了分析原因,可以考虑常规的B树索引,见图9-4。

10 50

10 ROWID 20 ROWID 30 ROWID 40 ROWID 50 ROWID 60 ROWID 70 ROWID

图9-4 常规的B树索引

可以看到,这是一个典型的常规B树索引。如果现在要为其添加新的数据,由于主键列的单调递增性,很明显不需要重新访问早先的叶子节点。接下的数据获得的主键为80,下一组数据的主键为90,依次类推。

这种方法在某些方面是具有优势的,由于它不存在向已经存在表项之间嵌入新的表项,所以不会发生叶子节点的数据块分割。这意味着,单调递增序列上的索引能够完全利用它的叶子节点,非常紧密地存放数据块,可以有效地利用存储空间。然而这种优势是需要付出代价的,每条记录都会占据最后的叶子结点,即使删除了先前的节点,也会导致同样的问题。这最终会导致对某一边的叶子节点的大量争用。

所以就需要设计一个规则,阻止用户在单调递增序列上建立索引后出现叶子节点偏向某一个方向。遗憾的时,序列编号通常是用来做表的主键的,每个主键都需要建立索引,如果用户没有建立索引,则Oracle也会自动建立这样的索引。但时,Oracle提供另一个索引机制,即反向键索引,它可以将添加的数据随机分散到索引中。

反向键索引是一种特殊类型的B树索引,在基于顺序递增列上建立索引时非常有用。反向键索引的工作原理非常简单,在存储结构方面它与常规的B树索引相同。然而,如果用户使用序列在表中输入新记录,则反向键索引首先反向每个列键值的字节,然后在反向后的新数据上进行索引。例如,如果用户输入的索引列为2008,则反向转换后为8002;2041反向转换后为1402。需要注意,刚才提及的两个序列编号是递增的,但是当进行反向键索引时且是非递增的。这意味如果将其添加到叶子结点,可能会在任意的叶子结点中进行。这样就使得新数据在值的范围上的分布通常比原来的有序数更均匀。

对于EMP表的EMPNO列而言,由于该列是顺序递增,所以为了均衡索引数据分布,应在该列上建立反向索引。创建反向键索引时只需要在CREATE INDEX语句中指定关键字REVERSE即可。例如,下面的语句为表EMP的EMPNO列创建了反向键索引:SQL> create index pk_emp

2 on emp(empno) reverse

3 tablespace users;

如果在该列上已经建立了普通B树索引,那么可以使用ALTER INDEX … REBUILD将其重新建立为反向键索引。示例如下:

SQL> alter index pk_emp

2 rebuild reverse;

索引已更改。

从Oracle 11g 开始,Oracle 会自动搜集表和索引的统计信息。当在WHERE 子句中引用反向索引列时,Oracle 会自动根据统计值确定是否引用反向索引。下面在WHERE 子句中引用反向键索引列,并显示其执行计划。 SQL> set autotrace on explain

SQL> select ename

2 from emp

3 where empno=7499;

ENAME

----------

ALLEN

执行计划

----------------------------------------------------------

Plan hash value: 2949544139

--------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 10 | 1 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 10 | 1 (0)| 00:00:01 |

|* 2 | INDEX UNIQUE SCAN | PK_EMP | 1 | | 0 (0)| 00:00:01 |

--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("EMPNO"=7499)

注 意

键的反转对用户而言是完全透明的,用户只需要像常规方式一样查询数据,对键的反转处理将由系统会自动完成。

相关文档
最新文档