1. 11gr2数据库的索引默认排序是asc,不是desc。
准备测试数据 create table test as select rownum as objectid,object_name from all_objects;
创建默认索引 create index idx_objectid_test on test(objectid);
select objectid from test; 将得到 1,2,3,4,5... 升序数据。
2. 降序索引的作用1-去掉sort 操作
若对上面表数据执行
select *from test order by objectid asc; 执行计划中没有sort操作,且显示 INDEX FULL SCAN + TABLE ACCESS BY INDEX ROWID,用时14.42 s
select *from test order by objectid desc; 执行计划中没有sort操作,且显示 INDEX FULL SCAN DESCENDING + TABLE ACCESS BY INDEX ROWID,用时14.12 s
3. 降序索引作用2--多列索引
下面的例子可以说明。
- tony@ORA11GR2> create table t as select * from all_objects;
- Table created.
- tony@ORA11GR2> create index t_idx on t(owner,object_type,object_name);
- Index created.
- tony@ORA11GR2> exec dbms_stats.gather_table_stats( user, 'T');
- PL/SQL procedure successfully completed.
- tony@ORA11GR2> set autotrace traceonly explain
- tony@ORA11GR2> select owner, object_type, object_name from t
- 2 where owner between 'T' and 'Z'
- 3 and object_type is not null
- 4 order by owner DESC, object_type DESC;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 2685572958
- -------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 13838 | 567K| 102 (0)| 00:00:02 |
- |* 1 | INDEX RANGE SCAN DESCENDING| T_IDX | 13838 | 567K| 102 (0)| 00:00:02 |
- -------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 1 - access("OWNER">='T' AND "OWNER"<='Z')
- filter("OBJECT_TYPE" IS NOT NULL)
Oracle会向前读索引,所以查询计划中没有排序。
但是如果有一些列按升序排列,一些列按降序排列,会有不同,如下:
- tony@ORA11GR2> select owner, object_type, object_name from t
- 2 where owner between 'T' and 'Z'
- 3 and object_type is not null
- 4 order by owner DESC, object_type ASC;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 2813023843
- -----------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
- -----------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 13838 | 567K| | 255 (1)| 00:00:04 |
- | 1 | SORT ORDER BY | | 13838 | 567K| 720K| 255 (1)| 00:00:04 |
- |* 2 | INDEX RANGE SCAN| T_IDX | 13838 | 567K| | 102 (0)| 00:00:02 |
- -----------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("OWNER">='T' AND "OWNER"<='Z')
- filter("OBJECT_TYPE" IS NOT NULL)
可以看到现在必须执行排序操作。
但是如果改用降序索引(使用DESC关键字),有如下结果,可以看到现在不需要排序操作了。
- tony@ORA11GR2> drop index desc_t_idx;
- Index dropped.
- tony@ORA11GR2> create index desc_t_idx on t(owner desc,object_type,object_name);
- Index created.
- tony@ORA11GR2> select owner, object_type, object_name from t
- 2 where owner between 'T' and 'Z'
- 3 and object_type is not null
- 4 order by owner DESC, object_type ASC;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 2494308350
- -------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 13838 | 567K| 4 (0)| 00:00:01 |
- |* 1 | INDEX RANGE SCAN| DESC_T_IDX | 13838 | 567K| 4 (0)| 00:00:01 |
- -------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 1 - access(SYS_OP_DESCEND("OWNER")>=HEXTORAW('A5FF') AND
- SYS_OP_DESCEND("OWNER")<=HEXTORAW('ABFF') )
- filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("OWNER"))>='T' AND
- SYS_OP_UNDESCEND(SYS_OP_DESCEND("OWNER"))<='Z' AND "OBJECT_TYPE" IS NOT
- NULL)