Oracle中ASSM模式下,全表扫描的L3块的逻辑读的影响

前言:
本问题由之前的实验拓展遗留的一些疑问,详见: http://blog.itpub.net/30174570/viewspace-2140241/
排除db_file_multiblock_read_count参数和动态采样(详见: http://blog.itpub.net/30174570/viewspace-2140240/ )的影响。

操作系统环境:
  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.        131           1          88
  11.        132          89         171
  12.        133         172         251
  13.        134         252         329
  14.        135         330         407
  15.        136         408         487
  16.        137         488         567
  17.        138         568         646
  18.        139         647         724
  19.        140         725         798
  20.        141         799         873

  21.     BLOCK# MIN(ROWNUM) MAX(ROWNUM)
  22. ---------- ----------- -----------
  23.        142         874         946
  24.        143         947        1022
  25.        145        1023        1104
  26.        146        1105        1179
  27.        147        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        128          8    --128 129 130 131 132 133 134 135
  33.          1          6        136          8
  34.          2          6        144          8

引出问题:
  1. SYS@proc> alter system set db_file_multiblock_read_count=1; --避免该参数的影响

  2. System altered.

  3. SYS@proc> show parameter db_file_multiblock_read_count

  4. NAME                                 TYPE        VALUE
  5. ------------------------------------ ----------- ------------------------------
  6. db_file_multiblock_read_count        integer     1

  7. SYS@proc> analyze table t compute statistics;   --避免动态采样的影响

  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     130     1
  21.      6     131     1
  22.      6     132     1
sql语句"select count(*) from t where rownum<=171"只读取了131,132两个块,但是130也被读取进去,这里读取该块的作用是什么?

实验过程:
  1. SYS@proc> alter system flush buffer_cache;

  2. System altered.

  3. 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;

  4. no rows selected

  5. SYS@proc> select HEADER_FILE,HEADER_BLOCK from dba_segments where owner='SYS' and segment_name='T';   --该语句可确定段头块是130

  6. HEADER_FILE HEADER_BLOCK
  7. ----------- ------------
  8.           6          130

  9. 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;

  10. no rows selected

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

  12.   COUNT(*)
  13. ----------
  14.        171

  15. SYS@proc> set autotrace on
  16. SYS@proc> select count(*) from t where rownum<=171;

  17.   COUNT(*)
  18. ----------
  19.        171


  20. Execution Plan
  21. ----------------------------------------------------------
  22. Plan hash value: 239743108

  23. --------------------------------------------------------------------
  24. | Id  | Operation           | Name | Rows  | Cost (%CPU)| Time     |
  25. --------------------------------------------------------------------
  26. |   0 | SELECT STATEMENT    |      |     1 |    21   (0)| 00:00:01 |
  27. |   1 |  SORT AGGREGATE     |      |     1 |            |          |
  28. |*  2 |   COUNT STOPKEY     |      |       |            |          |
  29. |   3 |    TABLE ACCESS FULL| T    |  1200 |    21   (0)| 00:00:01 |
  30. --------------------------------------------------------------------

  31. Predicate Information (identified by operation id):
  32. ---------------------------------------------------

  33.    2 - filter(ROWNUM<=171)


  34. Statistics
  35. ----------------------------------------------------------
  36.      0 recursive calls
  37.      0 db block gets
  38.      4 consistent gets
  39.      0 physical reads
  40.      0 redo size
  41.    527 bytes sent via SQL*Net to client
  42.    523 bytes received via SQL*Net from client
  43.      2 SQL*Net roundtrips to/from client
  44.      0 sorts (memory)
  45.      0 sorts (disk)
  46.      1 rows processed

  47. SYS@proc> set autotrace off
  48. 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;

  49.      FILE#     DBABLK      STATE
  50. ---------- ---------- ----------
  51.          6        130          1
  52.          6        131          1
  53.          6        132          1
上述实验过程第9行处,得出段头块是130号块,在ASSM中,段头是第一个L3块。
为什么该处的逻辑读是4呢?全表扫描下,会跳过L1(块128)和L2(块129),直接读取段头L3和高水位线以下的所有块(为什么全表扫描只读了131和132,受到rownum的影响,详情见 http://blog.itpub.net/30174570/viewspace-2140240/ )。但是L3要读取两次,所以逻辑读为4。读取L3两次,一次读取Extent Map,一次读取Auxillary Map。

回到一开始的问题,Oracle通过读取L3段头块确定全表扫描应该读取的区和区中的数据块,这个就是为什么除了131和132这两个实际包含数据的数据块以外,还要读取130块的原因。

数据块130的部分dump信息:
  1. Extent Control Header
  2.   -----------------------------------------------------------------
  3.   Extent Header:: spare1: 0 spare2: 0 #extents: 3 #blocks: 24
  4.                   last map 0x00000000 #maps: 0 offset: 2716
  5.       Highwater:: 0x01800094 ext#: 2 blk#: 4 ext size: 8
  6.   #blocks in seg. hdr's freelists: 0
  7.   #blocks below: 20
  8.   mapblk 0x00000000 offset: 2
  9.                    Unlocked
  10.   --------------------------------------------------------
  11.   Low HighWater Mark :
  12.       Highwater:: 0x01800094 ext#: 2 blk#: 4 ext size: 8
  13.   #blocks in seg. hdr's freelists: 0
  14.   #blocks below: 20
  15.   mapblk 0x00000000 offset: 2
  16.   Level 1 BMB for High HWM block: 0x01800090
  17.   Level 1 BMB for Low HWM block: 0x01800090
  18.   --------------------------------------------------------
  19.   Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0
  20.   L2 Array start offset: 0x00001434
  21.   First Level 3 BMB: 0x00000000
  22.   L2 Hint for inserts: 0x01800081
  23.   Last Level 1 BMB: 0x01800090
  24.   Last Level II BMB: 0x01800081
  25.   Last Level III BMB: 0x00000000
  26.      Map Header:: next 0x00000000 #extents: 3 obj#: 89405 flag: 0x10000000
  27.   Inc # 0
  28.   Extent Map
  29.   -----------------------------------------------------------------
  30.    0x01800080 length: 8
  31.    0x01800088 length: 8
  32.    0x01800090 length: 8

  33.   Auxillary Map
  34.   --------------------------------------------------------
  35.    Extent 0 : L1 dba: 0x01800080 Data dba: 0x01800083           "0x01800083"->二进制:00000001 10000000 00000000 10000011
  36.    Extent 1 : L1 dba: 0x01800080 Data dba: 0x01800088            前10位是文件号,后22位是块号,0000000110->文件号:6,000000 00000000 10000011->数据块:131
  37.    Extent 2 : L1 dba: 0x01800090 Data dba: 0x01800091
  38.   --------------------------------------------------------

  39.    Second Level Bitmap block DBAs
  40.    --------------------------------------------------------
  41.    DBA 1: 0x01800081

  42. End dump data blocks tsn: 9 file#: 6 minblk 130 maxblk 130

  1. SYS@proc> select to_number('01800083','xxxxxxxx') from dual;

  2. TO_NUMBER('01800083','XXXXXXXX')
  3. --------------------------------
  4.                         25165955

  5. SYS@proc> select dbms_utility.data_block_address_file(25165955) from dual;

  6. DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(25165955)
  7. ----------------------------------------------
  8.                                              6

  9. SYS@proc> select dbms_utility.data_block_address_block(25165955) from dual;

  10. DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(25165955)
  11. -----------------------------------------------
  12.                                             131

其他拓展:
  1. SYS@proc> --16进制数0x01800080转换为10进制数
  2. SYS@proc> select to_number('01800080','xxxxxxxx') from dual;

  3. TO_NUMBER('01800080','XXXXXXXX')
  4. --------------------------------
  5.                         25165952

  6. SYS@proc> --10进制25165952转换为16进制
  7. SYS@proc> select to_char(25165952,'xxxxxxxx') from dual;

  8. TO_CHAR(2
  9. ---------
  10.   1800080

  11. SYS@proc> --2进制转换为10进制
  12. SYS@proc> select bin_to_num(1,1,0,1) a,bin_to_num(1,0) b from dual;

  13.          A          B
  14. ---------- ----------
  15.         13          2

  16. SYS@proc> select bin_to_num(1,1,1,0,1) from dual;

  17. BIN_TO_NUM(1,1,1,0,1)
  18. ---------------------
  19.                    29


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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值