在实际的生成环境中,过滤条件一般都是绑定变量,我们无法控制传参究竟传入哪个值,这就不能确定返回数据究竟是多还是少了,所以,建议最好将排序的列包含在索引中。
但是要注意:如果排序列有多个列,创建索引的时候,我们要将所有的排序列包含在索引中,并且要注意排序列先后顺序,而且还要注意列时升序还是降序。如果分页语句中排序列只有一个列,但是是降序显示的,创建索引的时候就没必要降序创建索引了,我们可以使用hint:index_desc 让索引降序扫描就可以了。
例子:
(创建索引,只能是object_id在前,object_name在后,另外object_name是降序显示的,那么在创建索引的时候,还要指定object_name列降序排序。下面的sql也没有过滤条件,在创建索引的时候还要加个常量,如下所示:)
SQL> create index idx_test_2 on t_test(object_id,object_name desc,0); ---创建一个组合索引,包含owner字段
SQL> select * from (select * from (select a.*,rownum rn from (select /*+ index(t_test idx_test_2) */ * from t_test order by object_id,object_name desc) a ) where rownum <=10) where rn >=1;
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
----------------------------------------
SQL_ID g8zgbvt1u1qjq, child number 0
-------------------------------------
select * from (select * from (select a.*,rownum rn from (select /*+
index(t_test idx_test_2) */ * from t_test order by
object_id,object_name desc) a ) where rownum <=10) where rn >=1
Plan hash value: 2251915778
------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 |00:00:00.01 | 5 | 1 |
|* 1 | VIEW | | 1 | 10 | 10 |00:00:00.01 | 5 | 1 |
|* 2 | COUNT STOPKEY | | 1 | | 10 |00:00:00.01 | 5 | 1 |
| 3 | VIEW | | 1 | 80700 | 10 |00:00:00.01 | 5 | 1 |
| 4 | COUNT | | 1 | | 10 |00:00:00.01 | 5 | 1 |
| 5 | VIEW | | 1 | 80700 | 10 |00:00:00.01 | 5 | 1 |
| 6 | TABLE ACCESS BY INDEX ROWID| t_test | 1 | 80700 | 10 |00:00:00.01 | 5 | 1 |
| 7 | INDEX FULL SCAN | IDX_test_2 | 1 | 80700 | 10 |00:00:00.01 | 3 | 1 |
------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RN">=1)
2 - filter(ROWNUM<=10)
Note
-----
- dynamic sampling used for this statement (level=2)
31 rows selected.
如果在创建索引的时候没有指定 object_name列降序排序,那么执行计划中会出现sort order by。因为索引中排序和分页语句中排序不一致,如: