Oracle中db_file_multiblock_read_count参数探究

2017.04.19的实验探究,这里补上
前言:
对于该参数首次遇到的地方是关于证明"一个查询执行后、抓取记录时,抓取到哪条记录,才会去读相应的块。Oracle并不预先读取所有的块,构造一个结果集,然后从结果集中返回所查询的记录"的时候,该参数造成了一定的影响。有时间再将该实验整理。
拓展来源 http://www.itpub.net/thread-950711-1-1.html
这里研究一下db_file_multiblock_read_count的作用。

网上的资料:
Oracle在读取数据时一次读取的最大block的数量。
理论上,最大db_file_multiblock_read_count和系统IO能力应该有如下关系:
max(db_file_multiblock_read_count) = MaxOsIOsize/db_block_size
当然这个max(db_file_multiblock_read_count)还要受Oracle的限制,
目前Oracle所支持的最大db_file_multiblock_read_count 值为128.

Oracle 初始化参数 DB_FILE_MULTIBLOCK_READ_COUNT (MBRC) 默认值一般是比较低的,在进行一些比较大的数据操作的时候,恰当的调整当前 Session 的 MBRC 的值可能会在 IO 上节省一点时间。(这里抛出一个问题,数据泵之类的工具导出数据时怎么设置session层面的参数)。
DB_FILE_MULTIBLOCK_READ 这个参数的值并不是可以无限大, 大多数平台下的 Oracle 都是 128。一般 Oracle 的 Block Size 是 8K 。128*8K=1M 。 这个 1M 是大多数操作系统一次最大 I/O 的限制。前面的限制要从这个 1M 推回去,初始化参数 DB_FILE_MULTIBLOCK_READ_COUNT 的最大值之所以定为 128 ,也是一个比较保守的策略。

操作系统环境:
  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 t purge;

  2. Table dropped.

  3. SYS@proc> create table t as select * from dba_objects where rownum<=1200;

  4. Table created.

  5. SYS@proc> alter table t move tablespace test;

  6. Table altered.

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

  8.     BLOCK# MIN(ROWNUM) MAX(ROWNUM)
  9. ---------- ----------- -----------
  10.        171           1          88
  11.        172          89         171
  12.        173         172         251
  13.        174         252         329
  14.        175         330         407
  15.        176         408         487
  16.        177         488         567
  17.        178         568         646
  18.        179         647         724
  19.        180         725         798
  20.        181         799         873

  21.     BLOCK# MIN(ROWNUM) MAX(ROWNUM)
  22. ---------- ----------- -----------
  23.        182         874         946
  24.        183         947        1022
  25.        185        1023        1104
  26.        186        1105        1179
  27.        187        1180        1200

  28. 16 rows selected.

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

  30.  EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
  31. ---------- ---------- ---------- ----------
  32.          0          6        168          8       --168 169 170 171 172 173 174 175
  33.          1          6        176          8       --176 177 178 179 180 181 182 183
  34.          2          6        184          8       --184 185 186 187 188 189 190 191

实验过程:
  1. SYS@proc> show parameter multibl

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

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

  6. System altered.

  7. SYS@proc> analyze table t compute statistics;   --避免动态采样的影响,详情影响结果见http://blog.itpub.net/30174570/viewspace-2140240/

  8. Table analyzed.

  9. SYS@proc> alter system flush buffer_cache;

  10. System altered.

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

  12. no rows selected

  13. SYS@proc> select count(*) from t where rownum<=171;

  14.   COUNT(*)
  15. ----------
  16.        171

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

  18.      FILE#     DBABLK      STATE
  19. ---------- ---------- ----------
  20.          6        170          1
  21.          6        171          1
  22.          6        172          1
  23.          6        173          1
  24.          6        174          1
  25.          6        175          1

  26. 6 rows selected.
现在分析一下结果为什么是6个块:
1. select count ( * ) from t where rownum < = 171该语句只读取了t表的前两个块171和172;
2.db_file_multiblock_read_count = 8 表明读取数据时Oracle一次读取的数据块会达到最大8个
3.170块并不包含实际数据,但是应该包含关于T表一些信息,所以每次都会读取。(待探究) 。因为不是读取数据过程,170块不算第一个块。
4.171,172自然不用说。这是读取的第一、二个块。
5.由于db_file_multiblock_read_count影响,接下去应该读取多6个块,跟前边两个块凑足8个。
 但是这里却只读了173,174,175三个块。原因见6。
6.实际上描述是“在读取数据时一次读取的最大block的数量”,这里达不到8个是因为另外一个因素,读取多余的块的时候遇到区的尽头就停止读取,受到区范围的影响
 从上边实验数据知道,0号区的块是168 169 170 171 172 173 174 175,刚好175是0号区最后一个块,所以此次只读了6个块。
从10046结果看:
  1. WAIT #139854147886688: nam='Disk file operations I/O' ela= 454 FileOperation=2 fileno=6 filetype=2 obj#=89310 tim=1482082121461330
  2. WAIT #139854147886688: nam='db file sequential read' ela= 21 file#=6 block#=170 blocks=1 obj#=89310 tim=1482082121461405
  3. WAIT #139854147886688: nam='db file scattered read' ela= 41 file#=6 block#=171 blocks=5 obj#=89310 tim=1482082121461586
oracle分两次io读取,第一次获取必要信息,第二次才是获取数据时的io,受到区范围的影响,第二次io读取了5个块。

网友到这里若是看得懂,那么将db_file_multiblock_read_count设置为4,结果应该读取哪几个块。
我们先分析在验证:
170 171 172 173 174
应该读取上述5个块。

验证过程:
  1. SYS@proc> alter system set db_file_multiblock_read_count=4;

  2. System altered.

  3. SYS@proc> alter system flush buffer_cache;

  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='T') and state<>0 order by dbablk;

  6. no rows selected

  7. SYS@proc> select count(*) from t where rownum<=171;

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

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

  12.      FILE#     DBABLK      STATE
  13. ---------- ---------- ----------
  14.          6        170          1
  15.          6        171          1
  16.          6        172          1
  17.          6        173          1
  18.          6        174          1

遗留或拓展问题:
1.数据泵之类的工具导出数据时怎么设置session层面的参数。
2.上述实验过程分析中的第3点,每次读取多余的不包含数据的块,技术原理以及细节,已解决,详情见http://blog.itpub.net/30174570/viewspace-2140813/

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30174570/viewspace-2140241/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/30174570/viewspace-2140241/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值