深入理解Oracle索引(5):反向索引的定义、缺点和适用场景

㈠ 定义

立一个反向索引将把每个列的键值(each column key value)按字节反向过来,对于组合键,列的顺序被保留,但每个列的字节都作了反向
例如:
表的某一列内容
……
1234
1235
1236
1237
……

建立正向索引
……
1234
1235
1236
1237
……
这四行放在同一个leaf block中。
如果事务A查询1234这行,同时事务B查询1235这行。那么就会在这个leaf block上发生I/O争用


建立反向索引
……
4321
5321
6321
7321
……
这四行放在四个不同leaf block中
如果事务A查询1234这行,同时事务B查询1235这行。是分别在两个leaf block上进行,不会发生I/O争用

很多事务访问同一个块,对同一个块并发操作产生的I/0竞争
反向索引能作为避免热点块的一个方法

㈡ 查找

user_indexes.index_type


scott@ORCL> create index idx_rev on emp(sal) reverse;

Index created.

scott@ORCL> select index_name,index_type from user_indexes where index_name='IDX_REV';

INDEX_NAME                     INDEX_TYPE
------------------------------ ---------------------------
IDX_REV                        NORMAL/REV


㈢ 它有什么缺点?

① if you use reverse key index,index range scan will not work
② 当应用需要获取一段范围的数据时,reverse key index将不会被使用,因为键值不是连续的排列的。在这种情况下,CBO将会选择全表扫描

测试:

hr@ORCL> drop table t purge;

Table dropped.

hr@ORCL> create table t (a number,b varchar2(20));

Table created.

hr@ORCL> ed   
Wrote file afiedt.buf

  1  begin
  2    for i in 1..20000
  3    loop
  4      insert into t values(i,to_char(sysdate,'yyyymmddhhmmss'));
  5      commit;
  6    end loop;
  7* end;
hr@ORCL> /

PL/SQL procedure successfully completed.

hr@ORCL> create index idx_t on t (a) reverse;

Index created.

hr@ORCL> set autot on exp

hr@ORCL> select * from t where a >=19989 and a <=19990;

         A B
---------- --------------------
     19989 20130224060219
     19990 20130224060219


Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |    50 |    19   (6)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T    |     2 |    50 |    19   (6)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("A">=19989 AND "A"<=19990)

Note
-----
   - dynamic sampling used for this statement

hr@ORCL> drop index idx_t;

Index dropped.

hr@ORCL> create index idx_t on t (a);

Index created.

hr@ORCL> analyze index idx_t compute statistics;

Index analyzed.

hr@ORCL> select * from t where a >=19989 and a <=19990;

         A B
---------- --------------------
     19989 20130224060219
     19990 20130224060219


Execution Plan
----------------------------------------------------------
Plan hash value: 1594971208

-------------------------------------------------------------------------------------
| Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |       |     2 |    50 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T     |     2 |    50 |     3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_T |     2 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("A">=19989 AND "A"<=19990)

Note
-----
   - dynamic sampling used for this statement


㈣ 什么时候使用它?

反向索引主要是建立在那些以序列号生成的列上,可以将本来是连在一起的index entry分散到不同的leaf block中去
当索引是从序列中取的时候,如果是一般的b-tree 索引,在大量的插入后会导致块的分裂以及树的倾斜,使用reverse key index可以使索引段条目被更均匀的分布


以,reverse index主要是缓解右向增长的索引右侧叶子节点的争用,对于查询意义不大,注意reverse索引可能导致无法走range scan
但用于解决被索引引起的热块问题倒是很不错的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值