使用全表扫描缓存大表的相关问题

问题:
有一个批量操作,需要依次更新一个大表的大部分数据,而数据库buffer cache足够大,可以容纳该表.
是否可以通过并行全表扫描(db scattered read)将该表读入buffer cache,避免单块读取(db sequential read)导致的大量物理IO?
后者物理读次数是前者物理读次数的db_file_multiblock_read_count(缺省为16)倍.

为了验证该方案,需要明确如下问题,在全表扫描时:
(1)将表的数据块缓存到buffer cache还是PGA?是否使用多块读?
(2)使用parallel提示情况下,缓存到buffer cache还是PGA?是否使用多块读?

1 测试表准备
create table t
as
select * from dba_objects;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as pg@dev95
 
SQL>
SQL> select bytes,blocks,extents from user_segments where segment_name='T';
 
     BYTES     BLOCKS    EXTENTS
---------- ---------- ----------
   9437184       1152         24
SQL> select extent_id,bytes,blocks from user_extents where segment_name='T';
 
 EXTENT_ID      BYTES     BLOCKS
---------- ---------- ----------
         0      65536          8
         1      65536          8
         2      65536          8
         3      65536          8
         4      65536          8
         5      65536          8
         6      65536          8
         7      65536          8
         8      65536          8
         9      65536          8
        10      65536          8
        11      65536          8
        12      65536          8
        13      65536          8
        14      65536          8
        15      65536          8
        16    1048576        128
        17    1048576        128
        18    1048576        128
        19    1048576        128
        20    1048576        128
        21    1048576        128
        22    1048576        128
        23    1048576        128
 
24 rows selected

SQL> select object_id,data_object_id from user_objects where object_name='T';
 
 OBJECT_ID DATA_OBJECT_ID
---------- --------------
    155073         155073
 
SQL> select file#,block#,class#,status from v$bh where bjd=155073;
 
     FILE#     BLOCK#     CLASS# STATUS
---------- ---------- ---------- -------
         6     253578          8 xcur
        16      56457          8 xcur
        12      30649          8 xcur
        15      57481          8 xcur
        12      30665          8 xcur
        20      26890          8 xcur
        19      23306          8 xcur
        15      57497          8 xcur
        12      30681          8 xcur
        18      44682          8 xcur
        12      30634          9 xcur
         7     160905          8 xcur
        12      30697          8 xcur
        17     555273          8 xcur
        16      56458          8 xcur
         8     126217          8 xcur
        12      30713          8 xcur
         6     253577          8 xcur
        12      30635          4 xcur
         7     160906          8 xcur
        17     555274          8 xcur
        20      26889          8 xcur
        19      23305          8 xcur
         8     126218          8 xcur
        18      44681          8 xcur
        12      30633          8 xcur
 
26 rows selected

2 全表扫描缓存到buffer cache还是pga?是否使用多块读?
结论:缓存到buffer cache;使用了多块读。

SQL>
SQL> alter system flush shared_pool;
 
System altered
SQL> alter system flush buffer_cache;
 
System altered
 
SQL>
SQL>
SQL> select status, count(*) from v$bh where bjd = 155073 group by status;
free          1026
SQL> select statistic_name,value
  2    from v$segment_statistics ss
  3   where wner = user
  4     and object_name = 'T'
  5     and value>0
  6  order by 2;
segment scans                                                             1
db block changes                                                        256
physical writes direct                                                 1125
physical reads                                                         1126
physical writes                                                        1151
logical reads                                                          2704
space used                                                          9216000
space allocated                                                     9437184
 
8 rows selected
SQL> select sid, name, value
  2    from v$mystat ses, v$statname sn
  3   where ses.STATISTIC# = sn.STATISTIC#
  4     and value > 0
  5     and name like '%read%'
  6   order by 3;
       822 physical read total multi block requests                                 95
       822 physical read total IO requests                                         694
       822 physical read IO requests                                               694
       822 physical reads cache prefetch                                          1018
       822 physical reads                                                         1712
       822 physical reads cache                                                   1712
       822 no work - consistent read gets                                       641666
       822 session logical reads                                               1094037
       822 physical read total bytes                                          14024704
       822 physical read bytes                                                14024704
 
10 rows selected
SQL> select event, total_waits
  2    from v$session_event
  3   where sid = 822
  4     and wait_class = 'User I/O'
  5   order by 1;
db file scattered read                                                    95
db file sequential read                                                  606
 
SQL> select count(*) from t;
     80677
 
SQL> select sql_id,disk_reads,direct_writes,user_io_wait_time,buffer_gets,sql_text from v$sql where sql_text like '%count(*) from t%';
a3uxj45fdjv7m       1128             0             69853        1199  select count(*) from t
 
==〉v$sql.disk_reads:Number of disk reads for this child cursor


SQL> select * from table(dbms_xplan.display_cursor('a3uxj45fdjv7m'));
SQL_ID  a3uxj45fdjv7m, child number 0
-------------------------------------
 select count(*) from t
Plan hash value: 2966233522
-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |    93 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| T    | 80442 |    93   (3)| 00:00:01 |
-------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement
 
18 rows selected


SQL> select status, count(*) from v$bh where bjd = 155073 group by status;
xcur          1126  free           788
cr               1
==〉xcur:1126,说明缓存到了buffer cache

SQL> select statistic_name,value
  2    from v$segment_statistics ss
  3   where wner = user
  4     and object_name = 'T'
  5     and value>0
  6  order by 2;
segment scans                                                             1
db block changes                                                        256
physical writes direct                                                 1125
physical writes                                                        1151
physical reads                                                         2252 logical reads                                                          3904
space used                                                          9216000
space allocated                                                     9437184
 
8 rows selected
SQL> select sid, name, value
  2    from v$mystat ses, v$statname sn
  3   where ses.STATISTIC# = sn.STATISTIC#
  4     and value > 0
  5     and name like '%read%'
  6   order by 3;
       822 physical read total multi block requests                                189        822 physical read total IO requests                                         822        822 physical read IO requests                                               822        822 physical reads cache prefetch                                          2032        822 physical reads                                                         2854        822 physical reads cache                                                   2854        822 no work - consistent read gets                                       648919
       822 session logical reads                                               1107445
       822 physical read total bytes                                          23379968
       822 physical read bytes                                                23379968
 
==〉physical read total multi block requests:94,说明使用了多块读

SQL> select 94*16 from dual;
      1504
 
SQL> select event, total_waits
  2    from v$session_event
  3   where sid = 822
  4     and wait_class = 'User I/O'
  5   order by 1;
db file scattered read                                                   189 db file sequential read                                                  633

==〉db file scattered read:94,说明使用了多块读


3,使用并行提示,全表扫描缓存到buffer cache还是pga?是否使用多块读?
==> 读入pga;使用了多块读。

SQL> alter system flush shared_pool;
 
System altered
 
SQL> alter system flush buffer_cache;
 
System altered
 
SQL> select status, count(*) from v$bh where bjd = 155073 group by status;
free          1232
 
SQL>
SQL> select statistic_name,value
  2    from v$segment_statistics ss
  3   where wner = user
  4     and object_name = 'T'
  5     and value>0
  6  order by 2;
segment scans                                                             1
db block changes                                                        256
physical writes direct                                                 1125
physical writes                                                        1151
physical reads                                                         3388
logical reads                                                          7376
space used                                                          9216000
space allocated                                                     9437184
 
8 rows selected
SQL> select sid, name, value
  2    from v$mystat ses, v$statname sn
  3   where ses.STATISTIC# = sn.STATISTIC#
  4     and value > 0
  5     and name like '%read%'
  6   order by 3;
       822 physical read total multi block requests                                272
       822 physical read total IO requests                                        1546
       822 physical read IO requests                                              1546
       822 physical reads cache prefetch                                          3094
       822 physical reads                                                         4640
       822 physical reads cache                                                   4640
       822 no work - consistent read gets                                       671268
       822 session logical reads                                               1153284
       822 physical read total bytes                                          38010880
       822 physical read bytes                                                38010880
 
10 rows selected
SQL> select event, total_waits
  2    from v$session_event
  3   where sid = 822
  4     and wait_class = 'User I/O'
  5   order by 1;
db file scattered read                                                   272
db file sequential read                                                 1278
 
SQL> select /*+ parallel(t 8) */ count(*) from t;
     80677
 
SQL> select sql_id,disk_reads,direct_writes,user_io_wait_time,buffer_gets,sql_text from v$sql where sql_text like '%count(*) from t%';
6861j0dxkvvr4       1136             0              1056        1388  select /*+ parallel(t 8) */ count(*) from t
 
SQL> select * from table(dbms_xplan.display_cursor('6861j0dxkvvr4'));
SQL_ID  6861j0dxkvvr4, child number 0
 select /*+ parallel(t 8) */ count(*) from t
NOTE: cannot fetch plan for SQL_ID: 6861j0dxkvvr4, CHILD_NUMBER: 0
      Please verify value of SQL_ID and CHILD_NUMBER;
      It could also be that the plan is no longer in cursor cache (check v$sql_p
 
8 rows selected
SQL> explain plan for select /*+ parallel(t 8) */ count(*) from t
  2  ;
 
Explained
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3126468333
--------------------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Cost (%CPU)| Time     |    T
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |     1 |    13   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE        |          |     1 |            |          |
|   2 |   PX COORDINATOR       |          |       |            |          |
|   3 |    PX SEND QC (RANDOM) | :TQ10000 |     1 |            |          |  Q1,
|   4 |     SORT AGGREGATE     |          |     1 |            |          |  Q1,
|   5 |      PX BLOCK ITERATOR |          | 80677 |    13   (0)| 00:00:01 |  Q1,
|   6 |       TABLE ACCESS FULL| T        | 80677 |    13   (0)| 00:00:01 |  Q1,
--------------------------------------------------------------------------------
 
13 rows selected
 
SQL> select status, count(*) from v$bh where bjd = 155073 group by status;
xcur             1
free           720
==〉xcur:1,说明缓存到了pga
 
SQL>
SQL> select statistic_name,value
  2    from v$segment_statistics ss
  3   where wner = user
  4     and object_name = 'T'
  5     and value>0
  6  order by 2;
segment scans                                                           108
db block changes                                                        256
physical reads direct                                                  1125  physical writes direct                                                 1125
physical writes                                                        1151 
physical reads                                                         4514  logical reads                                                          8720
space used                                                          9216000
space allocated                                                     9437184
==〉physical reads direct:1125,说明使用了直接读


SQL> select sid, name, value
  2    from v$mystat ses, v$statname sn
  3   where ses.STATISTIC# = sn.STATISTIC#
  4     and value > 0
  5     and name like '%read%'
  6   order by 3;
       822 table scans (direct read)                                               107        822 physical read total multi block requests                                384        822 physical reads direct                                                  1125        822 physical read total IO requests                                        1733        822 physical read IO requests                                              1733        822 physical reads cache prefetch                                          3094
       822 physical reads cache                                                   4714
       822 physical reads                                                         5839        822 no work - consistent read gets                                       678775
       822 session logical reads                                               1167932
       822 physical read total bytes                                          47833088
       822 physical read bytes                                                47833088
 
==〉physical read total multi block requests:112,说明使用了多块读

SQL> select event, total_waits
  2    from v$session_event
  3   where sid = 822
  4     and wait_class = 'User I/O'
  5   order by 1;
db file scattered read                                                   272
db file sequential read                                                 1348

==〉db file scattered read:0,说明没有使用多块读或这种情况下的多块读不计入该事件计数。


4,遗留问题:
表上的cache属性,可以控制在全表扫描时把数据放置在LRU的热端。为了缓存大表,该属性是否影响缓存效果?

 

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

转载于:http://blog.itpub.net/18922393/viewspace-754214/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值