zoukankan      html  css  js  c++  java
  • 分页语句模板

    分页语句方法:
    
    1.rownum 
    2.row_number over(order by column) as 行号
    
    例子:
    create table page as select * from dba_objects;
    
    create index idx_page_1 on page(object_id,owner);
    BEGIN
      DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'QUERY',
                                    tabname          => 'PAGE',
                                    estimate_percent => 100,
                                    method_opt       => 'for all columns size skewonly',
                                    no_invalidate    => FALSE,
                                    degree           => 4,
                                    cascade          => TRUE);
    END;
    /
    
    比如这个SQL
    
    select object_id from 
    (
    select * from 
    (
    select  a.*,rownum rn
      from page a 
     where object_id >1000 and owner='SYS'
     order by object_id 
    ) where rownum<=20
    ) where rn>=0;
    
    SQL> select min(object_id) ,max(object_id) from page where owner='SYS' and object_id>1000;
    
    MIN(OBJECT_ID) MAX(OBJECT_ID)
    -------------- --------------
    	  1001	       111148
    
    
    SQL> set linesize 200
    SQL> set pagesize 200
    SQL> alter session set statistics_level=all; 
    
    会话已更改。
    
    SQL> select object_id from 
    (
    select * from 
    (
    select  a.*,rownum rn
      from page a 
     where object_id >1000 and owner='SYS'
     order by object_id 
    ) where rownum<=20
    ) where rn>=0;  2    3    4    5    6    7    8    9   10  
    
     OBJECT_ID
    ----------
          1001
          1002
          1003
          1004
          1005
          1006
          1007
          1008
          1009
          1010
          1011
          1012
          1013
          1014
          1015
          1016
          1017
          1018
          1019
          1020
    
    已选择20行。
    
    SQL>  select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID	dfb5uh3bgs11m, child number 0
    -------------------------------------
    select object_id from ( select * from ( select	a.*,rownum rn	from
    page a	where object_id >1000 and owner='SYS'  order by object_id )
    where rownum<=20 ) where rn>=0
    
    Plan hash value: 2584750597
    
    ---------------------------------------------------------------------------------------------
    | Id  | Operation	     | Name	  | Starts | E-Rows | A-Rows |	 A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |		  |	 1 |	    |	  20 |00:00:00.01 |	  4 |
    |*  1 |  VIEW		     |		  |	 1 |	 20 |	  20 |00:00:00.01 |	  4 |
    |*  2 |   COUNT STOPKEY      |		  |	 1 |	    |	  20 |00:00:00.01 |	  4 |
    |   3 |    VIEW 	     |		  |	 1 |  37466 |	  20 |00:00:00.01 |	  4 |
    |   4 |     COUNT	     |		  |	 1 |	    |	  20 |00:00:00.01 |	  4 |
    |*  5 |      INDEX RANGE SCAN| IDX_PAGE_1 |	 1 |  37466 |	  20 |00:00:00.01 |	  4 |
    ---------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("RN">=0)
       2 - filter(ROWNUM<=20)
       5 - access("OBJECT_ID">1000 AND "OWNER"='SYS' AND "OBJECT_ID" IS NOT NULL)
           filter("OWNER"='SYS')
    
    
    已选择27行。
    
    
    ORACLE升序扫描了索引,扫描20条记录就停止了.
    
    
    继续取下一页,
    SQL> select object_id from 
    (
    select * from 
    (
    select  a.*,rownum rn
      from page a 
     where object_id >1000 and owner='SYS'
     order by object_id 
    ) where rownum<=40
    ) where rn>=21;  2    3    4    5    6    7    8    9   10  
    
     OBJECT_ID
    ----------
          1021
          1022
          1023
          1024
          1025
          1026
          1027
          1028
          1029
          1030
          1031
          1032
          1033
          1034
          1035
          1036
          1037
          1038
          1039
          1040
    
    已选择20行。
    
    SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID	ftvyz3pxdfvyf, child number 0
    -------------------------------------
    select object_id from ( select * from ( select	a.*,rownum rn	from
    page a	where object_id >1000 and owner='SYS'  order by object_id )
    where rownum<=40 ) where rn>=21
    
    Plan hash value: 2584750597
    
    ---------------------------------------------------------------------------------------------
    | Id  | Operation	     | Name	  | Starts | E-Rows | A-Rows |	 A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |		  |	 1 |	    |	  20 |00:00:00.01 |	  4 |
    |*  1 |  VIEW		     |		  |	 1 |	 40 |	  20 |00:00:00.01 |	  4 |
    |*  2 |   COUNT STOPKEY      |		  |	 1 |	    |	  40 |00:00:00.01 |	  4 |
    |   3 |    VIEW 	     |		  |	 1 |  37466 |	  40 |00:00:00.01 |	  4 |
    |   4 |     COUNT	     |		  |	 1 |	    |	  40 |00:00:00.01 |	  4 |
    |*  5 |      INDEX RANGE SCAN| IDX_PAGE_1 |	 1 |  37466 |	  40 |00:00:00.01 |	  4 |
    ---------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("RN">=21)
       2 - filter(ROWNUM<=40)
       5 - access("OBJECT_ID">1000 AND "OWNER"='SYS' AND "OBJECT_ID" IS NOT NULL)
           filter("OWNER"='SYS')
    
    
    已选择27行。
    
    可以看到取下一页20行时,需要访问40条记录
    
    
    继续取下一页
    SQL> select object_id from 
    (
    select * from 
    (
    select  a.*,rownum rn
      from page a 
     where object_id >1000 and owner='SYS'
     order by object_id 
    ) where rownum<=60
    ) where rn>=41;  2    3    4    5    6    7    8    9   10  
    
     OBJECT_ID
    ----------
          1041
          1042
          1043
          1044
          1045
          1046
          1047
          1048
          1049
          1050
          1051
          1052
          1053
          1054
          1055
          1056
          1057
          1058
          1059
          1060
    
    已选择20行。
    
    SQL>  select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID	9xj40t5wq2n8v, child number 0
    -------------------------------------
    select object_id from ( select * from ( select	a.*,rownum rn	from
    page a	where object_id >1000 and owner='SYS'  order by object_id )
    where rownum<=60 ) where rn>=41
    
    Plan hash value: 2584750597
    
    ---------------------------------------------------------------------------------------------
    | Id  | Operation	     | Name	  | Starts | E-Rows | A-Rows |	 A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |		  |	 1 |	    |	  20 |00:00:00.01 |	  4 |
    |*  1 |  VIEW		     |		  |	 1 |	 60 |	  20 |00:00:00.01 |	  4 |
    |*  2 |   COUNT STOPKEY      |		  |	 1 |	    |	  60 |00:00:00.01 |	  4 |
    |   3 |    VIEW 	     |		  |	 1 |  37466 |	  60 |00:00:00.01 |	  4 |
    |   4 |     COUNT	     |		  |	 1 |	    |	  60 |00:00:00.01 |	  4 |
    |*  5 |      INDEX RANGE SCAN| IDX_PAGE_1 |	 1 |  37466 |	  60 |00:00:00.01 |	  4 |
    ---------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("RN">=41)
       2 - filter(ROWNUM<=60)
       5 - access("OBJECT_ID">1000 AND "OWNER"='SYS' AND "OBJECT_ID" IS NOT NULL)
           filter("OWNER"='SYS')
    
    
    已选择27行。
    
    取第三页时需要访问60条记录
    
    
    下面进行降序排序:
    
    
    SQL> select object_id from 
    (
    select * from 
    (
    select  a.*,rownum rn
      from page a 
     where object_id >1000 and owner='SYS'
     order by object_id desc
    ) where rownum<=20
    ) where rn>=0;  2    3    4    5    6    7    8    9   10  
    
     OBJECT_ID
    ----------
        111148
        111147
        111146
        111122
        111121
        111098
        111097
        111075
        111074
        111050
        111049
        111025
        111024
        111000
        110999
        110975
        110974
        110950
        110949
        110924
    
    已选择20行。
    
    SQL>  select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID	fbp9fbq0suc6c, child number 0
    -------------------------------------
    select object_id from ( select * from ( select	a.*,rownum rn	from
    page a	where object_id >1000 and owner='SYS'  order by object_id desc
    ) where rownum<=20 ) where rn>=0
    
    Plan hash value: 512348098
    
    --------------------------------------------------------------------------------------------------------
    | Id  | Operation			| Name	     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    --------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT		|	     |	    1 |        |     20 |00:00:00.01 |	     4 |
    |*  1 |  VIEW				|	     |	    1 |     20 |     20 |00:00:00.01 |	     4 |
    |*  2 |   COUNT STOPKEY 		|	     |	    1 |        |     20 |00:00:00.01 |	     4 |
    |   3 |    VIEW 			|	     |	    1 |  37466 |     20 |00:00:00.01 |	     4 |
    |   4 |     COUNT			|	     |	    1 |        |     20 |00:00:00.01 |	     4 |
    |*  5 |      INDEX RANGE SCAN DESCENDING| IDX_PAGE_1 |	    1 |  37466 |     20 |00:00:00.01 |	     4 |
    --------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("RN">=0)
       2 - filter(ROWNUM<=20)
       5 - access("OBJECT_ID" IS NOT NULL AND "OBJECT_ID">1000 AND "OWNER"='SYS')
           filter("OWNER"='SYS')
    
    
    已选择27行。
    
    ORACLE降序扫描了索引,扫描20条记录就停止了.
    
    继续降序取下一页:
    
    
    
    SQL> select object_id from 
    (
    select * from 
    (
    select  a.*,rownum rn
      from page a 
     where object_id >1000 and owner='SYS'
     order by object_id desc
    ) where rownum<=40
    ) where rn>=21;
      2    3    4    5    6    7    8    9   10  
     OBJECT_ID
    ----------
        109638
        109637
        105456
        105455
        104527
        104526
        104415
         94031
         87442
         87441
         87440
         87439
         87438
         87437
         87436
         87435
         87434
         87433
         87432
         87431
    
    已选择20行。
    
    SQL> 
    SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    SQL_ID	09ryhg66tgad5, child number 0
    -------------------------------------
    select object_id from ( select * from ( select	a.*,rownum rn	from
    page a	where object_id >1000 and owner='SYS'  order by object_id desc
    ) where rownum<=40 ) where rn>=21
    
    Plan hash value: 512348098
    
    --------------------------------------------------------------------------------------------------------
    | Id  | Operation			| Name	     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    --------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT		|	     |	    1 |        |     20 |00:00:00.01 |	    31 |
    |*  1 |  VIEW				|	     |	    1 |     40 |     20 |00:00:00.01 |	    31 |
    |*  2 |   COUNT STOPKEY 		|	     |	    1 |        |     40 |00:00:00.01 |	    31 |
    |   3 |    VIEW 			|	     |	    1 |  37466 |     40 |00:00:00.01 |	    31 |
    |   4 |     COUNT			|	     |	    1 |        |     40 |00:00:00.01 |	    31 |
    |*  5 |      INDEX RANGE SCAN DESCENDING| IDX_PAGE_1 |	    1 |  37466 |     40 |00:00:00.01 |	    31 |
    --------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("RN">=21)
       2 - filter(ROWNUM<=40)
       5 - access("OBJECT_ID" IS NOT NULL AND "OBJECT_ID">1000 AND "OWNER"='SYS')
           filter("OWNER"='SYS')
    
    
    已选择27行。
    
    
    这个时候降序分页取下一页需要访问40条记录。
    
    
    总结:
    1.分页语句必须走索引,在分页语句的WHERE 条件列和order by列上创建组合索引
    
    2.分页语句两边快,越到中间越慢,因为索引要访问的记录更多

  • 相关阅读:
    024.Kubernetes掌握Pod-部署MongoDB
    023.Kubernetes掌握Pod-Pod扩容和缩容
    附010.Kubernetes永久存储之GlusterFS超融合部署
    附009.Kubernetes永久存储之GlusterFS独立部署
    022.Kubernetes掌握Pod-Pod升级和回滚
    021.Kubernetes掌握Pod-Pod调度策略
    020.Kubernetes掌握Pod-Pod基础使用
    018.Kubernetes二进制集群插件metrics-dashboard
    016.Kubernetes二进制集群插件coredns
    .NET Core 3.0之深入源码理解ObjectPool(二)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13349757.html
Copyright © 2011-2022 走看看