zoukankan      html  css  js  c++  java
  • rowid paging benefit from 11g new feature

    rowid paging benefit from 11g new feature

    Source:

    http://dbakevin.blogspot.com/2012/04/rowid-paging-benifit-from-11g-new.html

    Need proxy to access the URL above -- http://www.51proxied.com/

     

    Consider below request:
    We need to get the 900 to 1000 records after ordered by time.

    We call this kind of request as "paging".  Because in most case we encounter this kind of request in web page's redirect buttons:  page 1, page 2, page 3.....  
    We can jump to any page via clicking the conrrespoding buttion.

    There are two kinds of paging method in oracle: Rownum paging and Rowid paging.
    Almost all the documents which i read all announce that rowid is a better method then rownum for paging.
    They said:
    For the first a few pages, two methods have similiar performance.But as long as the page number become bigger and bigger, rowid paging perform better and better then rownum paging.



    Pay attention to the red part. Is that really true?  Let's make a experiment. 

    First test in 11g. Create test table as below:

    11gR2 >create table test(id number,status VARCHAR2(7),type VARCHAR2(19),created date);
    Table created.
    11gR2 >insert into test select OBJECT_ID,STATUS,OBJECT_TYPE,CREATED from dba_objects;
    12926 rows created.
    11gR2 >alter table test modify created not null;
    Table altered.
    11gR2 >create index test_ind1 on test(CREATED);
    Index created.
    11gR2 >ANALYZE TABLE TEST compute statistics;
    Table analyzed.
    
    

    We are going to read row 900-1000 from table test order by created.

    Test 11g paging with rownum method:

    11gR2 >select *
           from (
                 select rownum rn,t.*
                 from
                 (select  id,status,type,created from test order by created) t
                 where rownum<1000)
           where rn >900;  
    99 rows selected.
    --------------------------------------------------------------------------------------------
    | Id  | Operation                      | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT               |           |   999 | 50949 |     9   (0)| 00:00:01 |
    |*  1 |  VIEW                          |           |   999 | 50949 |     9   (0)| 00:00:01 |
    |*  2 |   COUNT STOPKEY                |           |       |       |            |          |
    |   3 |    VIEW                        |           |   999 | 37962 |     9   (0)| 00:00:01 |
    |   4 |     TABLE ACCESS BY INDEX ROWID| TEST      | 12926 |   277K|     9   (0)| 00:00:01 |
    |   5 |      INDEX FULL SCAN           | TEST_IND1 |   999 |       |     4   (0)| 00:00:01 |
    --------------------------------------------------------------------------------------------
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
             22  consistent gets
              0  physical reads
              0  redo size
           3703  bytes sent via SQL*Net to client
            590  bytes received via SQL*Net from client
              8  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             99  rows processed
    




    Test 11g paging with rowid method:

    11gR2 >select /*+ ordered use_nl(p s) */ *
          from (
                select rownum rn,rd
                from (select  rowid rd from test order by created)
                t where rownum<1000) p,
                test s
          where rn>900 and p.rd=s.rowid;  2    3    4    5    6    7
    99 rows selected.
    -----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |   999 | 52947 |  1003   (0)| 00:00:13 |
    |   1 |  NESTED LOOPS               |           |   999 | 52947 |  1003   (0)| 00:00:13 |
    |*  2 |   VIEW                      |           |   999 | 24975 |     4   (0)| 00:00:01 |
    |*  3 |    COUNT STOPKEY            |           |       |       |            |          |
    |   4 |     VIEW                    |           |   999 | 11988 |     4   (0)| 00:00:01 |
    |   5 |      INDEX FULL SCAN        | TEST_IND1 | 12926 |   239K|     4   (0)| 00:00:01 |
    |   6 |   TABLE ACCESS BY USER ROWID| TEST      |     1 |    28 |     1   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------------
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
             19  consistent gets
              0  physical reads
              0  redo size
           5450  bytes sent via SQL*Net to client
            590  bytes received via SQL*Net from client
              8  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             99  rows processed
    



    From the red part we can see rowid paging(19 logic read)  do  better then  rownum paging(22 logic read).
    The reason is rowid method reduce the "TABLE ACCESS BY ROWID" for first 900 rows.


    Let's check in 10g:
    Build the Test table as excatly the same with 11g, created the index and gathered stats.

    Test 10g paging with rownum method:

    10gR2 >select *
           from (
                 select rownum rn,t.*
                 from
                 (select  id,status,type,created from test order by created) t
                 where rownum<1000)
           where rn >900;  
    99 rows selected.
    --------------------------------------------------------------------------------------------
    | Id  | Operation                      | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT               |           |   999 | 50949 |    17   (0)| 00:00:01 |
    |*  1 |  VIEW                          |           |   999 | 50949 |    17   (0)| 00:00:01 |
    |*  2 |   COUNT STOPKEY                |           |       |       |            |          |
    |   3 |    VIEW                        |           |   999 | 37962 |    17   (0)| 00:00:01 |
    |   4 |     TABLE ACCESS BY INDEX ROWID| TEST      | 45620 |  1113K|    17   (0)| 00:00:01 |
    |   5 |      INDEX FULL SCAN           | TEST_IND1 |   999 |       |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------------------------
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
             19  consistent gets
              0  physical reads
              0  redo size
           3842  bytes sent via SQL*Net to client
            558  bytes received via SQL*Net from client
              8  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             99  rows processed
    



    19 logic read, very close to 11g. It is a normal value and close to our expected.

    Test 10g paging with rowid method:

    10gR2 >select /*+ ordered use_nl(p s) */ *
          from (
                select rownum rn,rd
                from (select  rowid rd from test order by created)
                t where rownum<200) p,
                test s
          where rn>100 and p.rd=s.rowid;
    99 rows selected.
    -----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |   199 | 11144 |   261   (1)| 00:00:04 |
    |   1 |  NESTED LOOPS               |           |   199 | 11144 |   261   (1)| 00:00:04 |
    |*  2 |   VIEW                      |           |   199 |  4975 |    62   (2)| 00:00:01 |
    |*  3 |    COUNT STOPKEY            |           |       |       |            |          |
    |   4 |     VIEW                    |           | 45620 |   534K|    62   (2)| 00:00:01 |
    |   5 |      INDEX FULL SCAN        | TEST_IND1 | 45620 |   846K|    62   (2)| 00:00:01 |
    |   6 |   TABLE ACCESS BY USER ROWID| TEST      |     1 |    31 |     1   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------------
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
            108  consistent gets
              0  physical reads
              0  redo size
           5252  bytes sent via SQL*Net to client
            558  bytes received via SQL*Net from client
              8  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             99  rows processed
    




    wow, why logic turn to 108? The execution plan is same with 11g, but why so big difference in logic read?


          rownum    rowid
    11g:      22       19
    10g:      19      108


    Why?
    Below is the Reason:

    11gR2 >select rowid,id from test where rowid in ('AAADSHAABAAAH3hAAA','AAADSHAABAAAH3hAAB','AAADSHAABAAAH3hAAC','AAADSHAABAAAH3hAAD','AAADSHAABAAAH3hAAE','AAADSHAABAAAH3hAAF','AAADSHAABAAAH3hAAG','AAADSHAABAAAH3hAAH','AAADSHAABAAAH3hAAI','AAADSHAABAAAH3hAAJ');
    ROWID                      ID
    ------------------ ----------
    AAADSHAABAAAH3hAAA         20
    AAADSHAABAAAH3hAAB         46
    AAADSHAABAAAH3hAAC         28
    AAADSHAABAAAH3hAAD         15
    AAADSHAABAAAH3hAAE         29
    AAADSHAABAAAH3hAAF          3
    AAADSHAABAAAH3hAAG         25
    AAADSHAABAAAH3hAAH         41
    AAADSHAABAAAH3hAAI         54
    AAADSHAABAAAH3hAAJ         40
    10 rows selected.
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
              2  consistent gets
              0  physical reads
              0  redo size
            875  bytes sent via SQL*Net to client
            524  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             10  rows processed
    
    10gR2 >select rowid,id from test where rowid in ('AAAzo5AABAAAKnWAAA','AAAzo5AABAAAKnWAAB','AAAzo5AABAAAKnWAAC','AAAzo5AABAAAKnWAAD','AAAzo5AABAAAKnWAAE','AAAzo5AABAAAKnWAAF','AAAzo5AABAAAKnWAAG','AAAzo5AABAAAKnWAAH','AAAzo5AABAAAKnWAAI','AAAzo5AABAAAKnWAAJ');
    ROWID                      ID
    ------------------ ----------
    AAAzo5AABAAAKnWAAA         30
    AAAzo5AABAAAKnWAAB          8
    AAAzo5AABAAAKnWAAC         14
    AAAzo5AABAAAKnWAAD         34
    AAAzo5AABAAAKnWAAE         45
    AAAzo5AABAAAKnWAAF         39
    AAAzo5AABAAAKnWAAG         47
    AAAzo5AABAAAKnWAAH         51
    AAAzo5AABAAAKnWAAI         11
    AAAzo5AABAAAKnWAAJ         48
    10 rows selected.
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
             10  consistent gets
              0  physical reads
              0  redo size
            861  bytes sent via SQL*Net to client
            492  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             10  rows processed
    




    A Rowid is made by: OOOOOOFFFBBBBBBRRR
    O is object id,F is file id,B is block id,R is row number.

    From above we can see, read 10 rows from same block in 11g cost 2 block read while in 10g cost 10 block read.

    Further research also confirmed in 10g, every rowid will gernerate an logic read, even all the rowid are come from same block.
    But in 11g some new machanism are introduced, if next rowid is in the same block with current  row, then current block can be reuse.




    --------------------------------------
    Regards,
    FangwenYu
  • 相关阅读:
    Zabbix客户端日志出现(Not all processes could be identified, 解决
    zabbix 本地编译安装
    redis 配置文件解释 以及集群部署
    Unix shell范例精解 课后题
    if __name__ == '__main__':用法
    爬取猫眼电影100榜单 代码
    CentOS编译安装软件过程中遇到zlib.h: No such file or directory
    Codeigniter添加Composer支持
    CodeIgniter composer.json安装第三类库操作
    使用composer命令加载vendor中的第三方类库 的方法
  • 原文地址:https://www.cnblogs.com/fangwenyu/p/2490885.html
Copyright © 2011-2022 走看看