• 【oracle】探讨Oracle新分页方案的实现方案


    在 https://www.cnblogs.com/heyang78/p/15754872.html 里我们见到了12c开始的offset新分页方案。

    在执行解释计划是看到了row_number()的身影,当时我猜测此分析函数即offset语法的根本。

    在下文里也试着实现一次,具体实现的语句就是:

    select * from
    (select a.*,row_number() over(order by name) as rn from emp7 a) tta
    where 【start】<tta.rn and tta.rn<=end

    在验证其正确性之前,首先创建emp7表及数据:

    --建表
    create table emp7(
        id number(3),
        name nvarchar2(20),
        primary key(id)
    )
    --充值
    insert into emp7(id,name) values(1,'Andy');
    insert into emp7(id,name) values(2,'Bill');
    insert into emp7(id,name) values(3,'Cindy');
    insert into emp7(id,name) values(4,'Douglas');
    insert into emp7(id,name) values(5,'Eliot');
    insert into emp7(id,name) values(6,'Felix');
    insert into emp7(id,name) values(7,'Green');
    insert into emp7(id,name) values(8,'Hilter');
    insert into emp7(id,name) values(9,'Jack');
    insert into emp7(id,name) values(10,'Tom');
    insert into emp7(id,name) values(11,'Zerg');
    insert into emp7(id,name) values(12,'宋江');
    insert into emp7(id,name) values(13,'林冲');
    insert into emp7(id,name) values(14,'鲁智深');
    insert into emp7(id,name) values(15,'李逵');
    insert into emp7(id,name) values(16,'武松');
    insert into emp7(id,name) values(17,'吴用');

    然后看第一页数据:

    select * from
    (select a.*,row_number() over(order by name) as rn from emp7 a) tta
    where 0<tta.rn and tta.rn<=5
            ID NAME                                             RN
    ---------- ---------------------------------------- ----------
             1 Andy                                              1
             2 Bill                                              2
             3 Cindy                                             3
             4 Douglas                                           4
             5 Eliot                                             5

    第二页数据:

    select * from
    (select a.*,row_number() over(order by name) as rn from emp7 a) tta
    where 5<tta.rn and tta.rn<=10
            ID NAME                                             RN
    ---------- ---------------------------------------- ----------
             6 Felix                                             6
             7 Green                                             7
             8 Hilter                                            8
             9 Jack                                              9
            10 Tom                                              10

    第三页数据:

    select * from
    (select a.*,row_number() over(order by name) as rn from emp7 a) tta
    where 10<tta.rn and tta.rn<=15
            ID NAME                                             RN
    ---------- ---------------------------------------- ----------
            11 Zerg                                             11
            17 吴用                                             12
            12 宋江                                             13
            15 李逵                                             14
            13 林冲                                             15

    第四页数据:

    select * from
    (select a.*,row_number() over(order by name) as rn from emp7 a) tta
    where 15<tta.rn and tta.rn<=20
            ID NAME                                             RN
    ---------- ---------------------------------------- ----------
            16 武松                                             16
            14 鲁智深                                           17

    这四爷数据和其它三种分页方案的结果一致,足以证明其正确性。

    在看看这种做法的效率。

    先创建emp8表及其数据:

    --emp8表建表语句:
    
    create table emp8(
        id number(12),
        name nvarchar2(30),
        primary key(id)
    )
    --充值:
    
    insert into emp8
    select rownum,dbms_random.String('*',dbms_random.value(1,30))
    from dual
    connect by level<10001

    要验证的SQL:

    select * from
    (select a.*,row_number() over(order by name) as rn from emp8 a) tta
    where 5500<tta.rn and tta.rn<=6500

    这个和其它三种方案都是一致的。

    跑解释计划:

    explain plan for
    select * from
    (select a.*,row_number() over(order by name) as rn from emp8 a) tta
    where 5500<tta.rn and tta.rn<=6500
    
    select * from table(dbms_xplan.display);

    结果:

    SQL> select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    Plan hash value: 2150022822
    
    --------------------------------------------------------------------------------
    -
    
    | Id  | Operation                | Name | Rows  | Bytes | Cost (%CPU)| Time
    |
    
    --------------------------------------------------------------------------------
    -
    
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT         |      | 10000 |   566K|    19  (11)| 00:00:01
    |
    
    |*  1 |  VIEW                    |      | 10000 |   566K|    19  (11)| 00:00:01
    |
    
    |*  2 |   WINDOW SORT PUSHED RANK|      | 10000 |   439K|    19  (11)| 00:00:01
    |
    
    |   3 |    TABLE ACCESS FULL     | EMP8 | 10000 |   439K|    17   (0)| 00:00:01
    |
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    
    --------------------------------------------------------------------------------
    -
    
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("TTA"."RN">5500 AND "TTA"."RN"<=6500)
       2 - filter(ROW_NUMBER() OVER ( ORDER BY "NAME")<=6500)
    
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    已选择20行。
    
    SQL>

    cost也是19,但冗余数据行没有及时甩脱,这个就留待日后提高吧。

    END

  • 相关阅读:
    多线程:多线程设计模式(一):总体介绍
    javascript:12种JavaScript MVC框架之比较
    mysql 查询死锁语句
    charles 抓包工具破解方法
    java 自定义log类
    git统计日期之间的代码改动行数
    mac/linux自带定时任务执行crontab的使用
    python MD5步骤
    python 操作excel读写
    python logger日志工具类
  • 原文地址:https://www.cnblogs.com/heyang78/p/15760969.html
Copyright © 2020-2023  润新知