Oracle中rownum对表的扫描方式性能上的影响深入探究

本文通过实验详细探讨了Oracle数据库中rownum对表扫描方式的影响,展示了不同设置下对数据读取效率的差异,揭示了rownum在数据库操作中的性能表现,并分析了相关优化策略。
摘要由CSDN通过智能技术生成
前言:
偶然发现rownum上加限定条件后,执行计划虽然是全表扫描,但是实际上却是只扫描了满足条件的行所在的数据块,也就是没有做全表扫描。
问题可以假设性描述为一条select语句的全表扫描,结果是1000行,加上rownum<=500之后,oracle是扫描了前500行所在的块,还是扫描了1000行后取前500行(前者性能要更好)。
构造数据进行探究。探究过程中影响的因素有
1.参数db_file_multiblock_read_count,关于该参详情可以读阅 http://blog.itpub.net/30174570/viewspace-2140241/
2.动态采样。

操作系统信息:
  1. [oracle@oracle ~]$ uname -a
  2. Linux oracle.example.com 2.6.32-431.el6.x86_64 #1 SMP Sun Nov 10 22:19:54 EST 2013 x86_64 x86_64 x86_64 GNU/Linux
  3. [oracle@oracle ~]$ lsb_release -a
  4. LSB Version:    :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
  5. Distributor ID: RedHatEnterpriseServer
  6. Description:    Red Hat Enterprise Linux Server release 6.5 (Santiago)
  7. Release:        6.5
  8. Codename:       Santiago

数据库版本:

  1. SYS@proc> select * from v$version where rownum<=1;

  2. BANNER
  3. --------------------------------------------------------------------------------
  4. Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

构造测试数据:

  1. SYS@proc> drop table test purge;

  2. Table dropped.

  3. SYS@proc> create table test tablespace test as select * from dba_objects where rownum<=1500;

  4. Table created.

  5. SYS@proc> select dbms_rowid.rowid_row_number(rowid) row# from test where rownum<=10;

  6.       ROW#
  7. ----------
  8.          0
  9.          1
  10.          2
  11.          3
  12.          4
  13.          5
  14.          6
  15.          7
  16.          8
  17.          9

  18. 10 rows selected.


  19. SYS@proc> select dbms_rowid.rowid_block_number(rowid) block#,min(rownum),max(rownum) from test group by dbms_rowid.rowid_block_number(rowid) order by dbms_rowid.rowid_block_number(rowid);

  20.     BLOCK# MIN(ROWNUM) MAX(ROWNUM)
  21. ---------- ----------- -----------
  22.        139           1          88
  23.        140          89         171
  24.        141         172         251
  25.        142         252         329
  26.        143         330         407
  27.        144         408         487
  28.        145         488         567
  29.        146         568         646
  30.        147         647         724
  31.        148         725         798
  32.        149         799         873

  33.     BLOCK# MIN(ROWNUM) MAX(ROWNUM)
  34. ---------- ----------- -----------
  35.        150         874         946
  36.        151         947        1022
  37.        161        1023        1104
  38.        162        1105        1179
  39.        163        1180        1261
  40.        164        1262        1342
  41.        165        1343        1418
  42.        166        1419        1496
  43.        167        1497        1500

  44. 20 rows selected.

  45. SYS@proc> select EXTENT_ID,FILE_ID,BLOCK_ID,BLOCKS from dba_extents where owner='SYS' and SEGMENT_NAME='TEST';

  46.  EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
  47. ---------- ---------- ---------- ----------
  48.          0          6        136          8    --136 137 138 139 140 141 142 143
  49.          1          6        144          8    --144 145 146 147 148 149 150 151
  50.          2          6        160          8    --160 161 162 163 164 165 166 167

实验 过程:
说明:由于该过程是做的全表扫描下对rownum加限定词后,扫描表的块是否发生减少,为了避免db_file_multiblock_read_count的影响,将其值设置为1。
  1. SYS@proc> show parameter multiblock

  2. NAME                                 TYPE        VALUE
  3. ------------------------------------ ----------- ------------------------------
  4. db_file_multiblock_read_count        integer     8

  5. SYS@proc> alter system set db_file_multiblock_read_count=1;

  6. System altered.

  1. SYS@proc> alter system flush buffer_cache;

  2. System altered.

  3. SYS@proc> alter system flush shared_pool;

  4. System altered.

  5. SYS@proc> select file#,dbablk,state from x$bh where obj=(select data_object_id from dba_objects where owner='SYS' and object_name='TEST') and state<>0 order by dbablk;

  6. no rows selected

  7. SYS@proc> select count(*) from test where rownum<=171;    --只读前两个块

  8.   COUNT(*)
  9. ----------
  10.        171

  11. SYS@proc> set pagesize 9999
  12. SYS@proc> select * from table(dbms_xplan.display_cursor(null,null,'advanced'));

  13. PLAN_TABLE_OUTPUT
  14. ------------------------------------------------------------------------------------
  15. SQL_ID  5h6qpq1adpkh8, child number 0
  16. -------------------------------------
  17. select count(*) from test where rownum<=171

  18. Plan hash value: 827909369

  19. --------------------------------------------------------------------
  20. | Id  | Operation           |
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值