Oracle优化之单表分页优化(5)

在实际的生成环境中,过滤条件一般都是绑定变量,我们无法控制传参究竟传入哪个值,这就不能确定返回数据究竟是多还是少了,所以,建议最好将排序的列包含在索引中。

但是要注意:如果排序列有多个列,创建索引的时候,我们要将所有的排序列包含在索引中,并且要注意排序列先后顺序,而且还要注意列时升序还是降序。如果分页语句中排序列只有一个列,但是是降序显示的,创建索引的时候就没必要降序创建索引了,我们可以使用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。因为索引中排序和分页语句中排序不一致,如:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/54dde0eed17e5e61c9154771a785f4c8.html