SORT ORDER BY STOPKEY

select  *  from ( select rownum as rn ,a.* from ( select  
*   from t100 a  
order by object_id desc )a where rownum<=40 ) a  where rn>=1


SQL> 
SQL> select count(*) from t100;

  COUNT(*)
----------
   3020896
   
 BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SYSTEM',
                                tabname          => 'T100',
                                estimate_percent => 100,
                                method_opt       => 'for all columns size repeat',
                                no_invalidate    => FALSE,
                                degree           => 8,
                                cascade          => TRUE);
END;

---高级执行计划:
11G:
alter session set statistics_level=all; ---再运行SQL

select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));


select *
  from (select rownum as rn, a.*
          from (select * from t100 a order by object_id desc) a
         where rownum <= 40) a
 where rn >= 1

SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-----------------------
SQL_ID	1h6g4u7aa6sqd, child number 1
-------------------------------------
select *   from (select rownum as rn, a.*	    from (select * from
t100 a order by object_id desc) a	   where rownum <= 40) a  where
rn >= 1

Plan hash value: 3078193190

-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation		 | Name | Starts | E-Rows | A-Rows |   A-Time	| Buffers | Reads  |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	 |	|      1 |	  |	40 |00:00:01.44 |   42846 |    111 |	   |	   |	      |
|*  1 |  VIEW			 |	|      1 |     40 |	40 |00:00:01.44 |   42846 |    111 |	   |	   |	      |
|*  2 |   COUNT STOPKEY 	 |	|      1 |	  |	40 |00:00:01.44 |   42846 |    111 |	   |	   |	      |
|   3 |    VIEW 		 |	|      1 |   3020K|	40 |00:00:01.44 |   42846 |    111 |	   |	   |	      |
|*  4 |     SORT ORDER BY STOPKEY|	|      1 |   3020K|	40 |00:00:01.44 |   42846 |    111 |  1186K|   567K| 1054K (0)|
|   5 |      TABLE ACCESS FULL	 | T100 |      1 |   3020K|   3020K|00:00:00.46 |   42846 |    111 |	   |	   |	      |
-------------------------------------------------------------------------------------------------------------------------------

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

   1 - filter("RN">=1)
   2 - filter(ROWNUM<=40)
   4 - filter(ROWNUM<=40)


已选择26行。


分页SQL返回40条记录,实际确需要访问 3020K 记录,显然不合理




创建索引:

 create index t100_idx1 on t100(object_id);

select  *  from ( select rownum as rn ,a.* from ( select  
*   from t100 a  
order by object_id desc )a where rownum<=40 ) a  where rn>=1


SQL>  select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-----------------------
SQL_ID	2umgv7yv9y4vu, child number 0
-------------------------------------
select *   from (select rownum as rn, a.*	    from (select * from
t100 a order by object_id desc) a	   where rownum <= 40) a  where
rn >= 1

Plan hash value: 3078193190

----------------------------------------------------------------------------------------------------------------------
| Id  | Operation		 | Name | Starts | E-Rows | A-Rows |   A-Time	| Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	 |	|      1 |	  |	40 |00:00:01.54 |   42846 |	  |	  |	     |
|*  1 |  VIEW			 |	|      1 |     40 |	40 |00:00:01.54 |   42846 |	  |	  |	     |
|*  2 |   COUNT STOPKEY 	 |	|      1 |	  |	40 |00:00:01.54 |   42846 |	  |	  |	     |
|   3 |    VIEW 		 |	|      1 |   3020K|	40 |00:00:01.54 |   42846 |	  |	  |	     |
|*  4 |     SORT ORDER BY STOPKEY|	|      1 |   3020K|	40 |00:00:01.54 |   42846 |  1186K|   567K| 1054K (0)|
|   5 |      TABLE ACCESS FULL	 | T100 |      1 |   3020K|   3020K|00:00:00.51 |   42846 |	  |	  |	     |
----------------------------------------------------------------------------------------------------------------------

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

   1 - filter("RN">=1)
   2 - filter(ROWNUM<=40)
   4 - filter(ROWNUM<=40)


已选择26行。


没有走索引


SQL> select *
  from (select rownum as rn, a.*
          from (select /*+ index(a t100_idx1)*/ * from t100 a order by object_id desc) a
         where rownum <= 40) a
 where rn >= 1
   2    3    4    5    6  ;

已选择40行。


执行计划
----------------------------------------------------------
Plan hash value: 3078193190

-----------------------------------------------------------------------------------------
| Id  | Operation		 | Name | Rows	| Bytes |TempSpc| Cost (%CPU)| Time	|
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	 |	|    40 |  8800 |	| 78467   (1)| 00:15:42 |
|*  1 |  VIEW			 |	|    40 |  8800 |	| 78467   (1)| 00:15:42 |
|*  2 |   COUNT STOPKEY 	 |	|	|	|	|	     |		|
|   3 |    VIEW 		 |	|  3020K|   596M|	| 78467   (1)| 00:15:42 |
|*  4 |     SORT ORDER BY STOPKEY|	|  3020K|   279M|   386M| 78467   (1)| 00:15:42 |
|   5 |      TABLE ACCESS FULL	 | T100 |  3020K|   279M|	| 11645   (1)| 00:02:20 |
-----------------------------------------------------------------------------------------

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

   1 - filter("RN">=1)
   2 - filter(ROWNUM<=40)
   4 - filter(ROWNUM<=40)


SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-----------------------
SQL_ID	1jx0gdw60vc3n, child number 1
-------------------------------------
select *   from (select rownum as rn, a.*	    from (select /*+
index(a t100_idx1)*/ * from t100 a where a.object_id is not null  order
by object_id desc) a	      where rownum <= 40) a  where rn >= 1

Plan hash value: 2711774789

----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation			| Name	    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT		|	    |	   1 |	      |     40 |00:00:06.25 |	 3027K|       |       | 	 |
|*  1 |  VIEW				|	    |	   1 |	   40 |     40 |00:00:06.25 |	 3027K|       |       | 	 |
|*  2 |   COUNT STOPKEY 		|	    |	   1 |	      |     40 |00:00:06.25 |	 3027K|       |       | 	 |
|   3 |    VIEW 			|	    |	   1 |	 3020K|     40 |00:00:06.25 |	 3027K|       |       | 	 |
|*  4 |     SORT ORDER BY STOPKEY	|	    |	   1 |	 3020K|     40 |00:00:06.25 |	 3027K|   149M|  4122K|  132M (0)|
|   5 |      TABLE ACCESS BY INDEX ROWID| T100	    |	   1 |	 3020K|   3020K|00:00:04.33 |	 3027K|       |       | 	 |
|*  6 |       INDEX FULL SCAN		| T100_IDX1 |	   1 |	 3020K|   3020K|00:00:00.78 |	 6697 |       |       | 	 |
----------------------------------------------------------------------------------------------------------------------------------

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

   1 - filter("RN">=1)
   2 - filter(ROWNUM<=40)
   4 - filter(ROWNUM<=40)
   6 - filter("A"."OBJECT_ID" IS NOT NULL)


已选择28行。


此时走索引了,但是仍旧访问了3020K ,显然不够优化
SQL> select *
  from (select rownum as rn, a.*
          from (select /*+ index_desc(a t100_idx1)*/ * from t100 a where a.object_id is not null  order by object_id desc) a
         where rownum <= 40) a
 where rn >= 1  2    3    4    5  
  6  ;


SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-----------------------
SQL_ID	9pv0wyn2mk187, child number 0
-------------------------------------
select *   from (select rownum as rn, a.*	    from (select /*+
index_desc(a t100_idx1)*/ * from t100 a where a.object_id is not null
order by object_id desc) a	    where rownum <= 40) a  where rn >= 1

Plan hash value: 4052825412

---------------------------------------------------------------------------------------------------------------
| Id  | Operation		       | Name	   | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	       |	   |	  1 |	     |	   40 |00:00:00.01 |	  46 |	    1 |
|*  1 |  VIEW			       |	   |	  1 |	  40 |	   40 |00:00:00.01 |	  46 |	    1 |
|*  2 |   COUNT STOPKEY 	       |	   |	  1 |	     |	   40 |00:00:00.01 |	  46 |	    1 |
|   3 |    VIEW 		       |	   |	  1 |	  40 |	   40 |00:00:00.01 |	  46 |	    1 |
|   4 |     TABLE ACCESS BY INDEX ROWID| T100	   |	  1 |	  40 |	   40 |00:00:00.01 |	  46 |	    1 |
|*  5 |      INDEX FULL SCAN DESCENDING| T100_IDX1 |	  1 |	3020K|	   40 |00:00:00.01 |	   6 |	    1 |
---------------------------------------------------------------------------------------------------------------

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

   1 - filter("RN">=1)
   2 - filter(ROWNUM<=40)
   5 - filter("A"."OBJECT_ID" IS NOT NULL)


已选择26行。

此时访问了40条记录,是最优化的

SORT ORDER BY STOPKEY

    Sorts a subset of the result according to the order by clause. Used for top-N queries if pipelined execution is not possible.



排序结果的子集根据order by子句

SORT ORDER BY STOPKEY 是指:

排序过后取数据 

走索引后返回 3020K|条 

是要对3020K|排序,所以效率低

你可能感兴趣的:(sql,查询优化)