范围查询用不到反向键索引

/*  
  结论:方向键索引可以消除索引热块访问竞争,是一个很不错的技术,只能该技术只能用在等值查询,而不能用在范围查询。
  以下是生产中的一个案例,有人讲索引建成了反向键索引,却忘记了该系统有大量范围查询,还在纠结为何范围查询用不到索引。
  这是一个建索引考虑不周的例子。  
*/

--这里说的是反向键索引的故事


drop table t purge;
create table t (id number,deal_date date,area_code number,nbr number,contents varchar2(4000));
set autotrace off
insert into t(id,deal_date,area_code,nbr,contents)
      select rownum,
             to_date( to_char(sysdate-365,'J')+TRUNC(DBMS_RANDOM.VALUE(0,700)),'J'),
             ceil(dbms_random.value(590,599)),
             ceil(dbms_random.value(18900000001,18999999999)),
             rpad('*',400,'*')
        from dual
      connect by rownum <= 100000;
commit;

create index idx_t_id on t(id) reverse;
set linesize 1000
set autotrace off
select index_name,index_type from user_indexes where table_name='T';
INDEX_NAME                     INDEX_TYPE
------------------------------ -----------
IDX_T_ID                       NORMAL/REV

set autotrace traceonly 
--以下语句缘何用不到索引。
select * from t where id=28;
执行计划
----------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |    69 |   138K|   401   (0)| 00:00:05 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T        |    69 |   138K|   401   (0)| 00:00:05 |
|*  2 |   INDEX RANGE SCAN          | IDX_T_ID |   486 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------


--不过奇怪的是,缘何下列语句却用不到索引,索引去哪儿?


select * from t where id>=28 and id<=50;
执行计划
----------------------------------------------------------
Plan hash value: 1601196873


--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   304 |   608K|  1709   (1)| 00:00:21 |
|*  1 |  TABLE ACCESS FULL| T    |   304 |   608K|  1709   (1)| 00:00:21 |
--------------------------------------------------------------------------
统计信息
------------------------------------------------------
          0  recursive calls
          0  db block gets
       6303  consistent gets
          0  physical reads
          0  redo size
       2263  bytes sent via SQL*Net to client
        426  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         23  rows processed

--原因在于这个索引不是普通索引,是为了避免热块竞争而建立的反向键索引,根本不支持范围查询,只支持等值查询。
请使用浏览器的分享功能分享到微信等