您的位置:首页 > 其它

Asktom:Single Block IO Vs Multi Block IO

2014-12-17 11:57 218 查看

Asktom:Single Block IO Vs Multi Block IO

You Asked

Tom:

I was reading this Oracle magazine


http://www.oracle.com/technetwork/issue-archive/2011/11-jul/o40asktom-402616.html


<quote>

A full index scan reads the index a block at a time, from start to finish, It uses single-block, not multiblock, I/O for this operation

A fast full index scan reads the entire index, unsorted, as it exists on disk, We use multiblock I/O and read all the leaf, branch, and root blocks

</quote>

create table t
nologging
as
select *
from all_objects;

create index t_ind on t(owner,object_type,object_name) nologging;

begin
dbms_stats.gather_table_stats(
ownname =>user,
tabname =>'T',
estimate_percent=>dbms_stats.auto_sample_size,
cascade=>true);
end;
/

rajesh@10GR2>
rajesh@10GR2>
rajesh@10GR2> exec show_space(user,'T_IND','INDEX');
l_total_blocks****************  448
l_total_bytes*****************  yes
l_unused_blocks***************  19
l_unused_bytes****************  155648
l_last_used_extent_file_id****  22
l_last_used_extent_block_id***  4873
l_last_used_block*************  13
l_unformatted_blocks**********  0
l_unformatted_bytes***********  0
l_fs1_blocks******************  0
l_fs1_bytes*******************  0
l_fs2_blocks******************  1
l_fs2_bytes*******************  8192
l_fs3_blocks******************  0
l_fs3_bytes*******************  0
l_fs4_blocks******************  0
l_fs4_bytes*******************  0
l_full_blocks*****************  414
l_full_bytes******************  3391488

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.06
rajesh@10GR2>
rajesh@10GR2>
rajesh@10GR2> set autotrace traceonly explain statistics;
rajesh@10GR2>
rajesh@10GR2> select owner,object_type,object_name
2  from t
3  order by owner,object_type,object_name;

58779 rows selected.

Elapsed: 00:00:02.48

Execution Plan
----------------------------------------------------------
Plan hash value: 607953271

--------------------------------------------------------------------------
| Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       | 58779 |  2296K|   417   (1)| 00:00:06 |
|   1 |  INDEX FULL SCAN | T_IND | 58779 |  2296K|   417   (1)| 00:00:06 |
--------------------------------------------------------------------------

Statistics
----------------------------------------------------------
1  recursive calls
0  db block gets
803  consistent gets
0  physical reads
0  redo size
1563107  bytes sent via SQL*Net to client
2984  bytes received via SQL*Net from client
393  SQL*Net roundtrips to/from client
0  sorts (memory)
0  sorts (disk)
58779  rows processed

rajesh@10GR2>
rajesh@10GR2> select owner,object_type,object_name
2  from t;

58779 rows selected.

Elapsed: 00:00:02.31

Execution Plan
----------------------------------------------------------
Plan hash value: 3351170763

------------------------------------------------------------------------------
| Id  | Operation            | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |       | 58779 |  2296K|    94   (3)| 00:00:02 |
|   1 |  INDEX FAST FULL SCAN| T_IND | 58779 |  2296K|    94   (3)| 00:00:02 |
------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
1  recursive calls
0  db block gets
810  consistent gets
1  physical reads
0  redo size
1566056  bytes sent via SQL*Net to client
2984  bytes received via SQL*Net from client
393  SQL*Net roundtrips to/from client
0  sorts (memory)
0  sorts (disk)
58779  rows processed

rajesh@10GR2>
rajesh@10GR2> set autotrace off
rajesh@10GR2>


Questions:

1) Size of index is 429 Blocks (448-19), INDEX FULL SCAN - is doing a single-block IO, if so why the above query needs 803 blocks (from buffer) to answer and why *NOT* 429 blocks?

2) How can i measure the total IO's used by a query? Say in INDEX FULL SCAN we are doing a single-block IO but Autotrace statistics shows that i am reading 803 blocks from buffer to answer this query. How do i know how many IO's is really spent in reading 803
blocks from buffer?

and we said...

1)
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:880343948514


it has to do with your arraysize and how many times Oracle has to revisit a block. If you use an arraysize of 2 - you would see about 58779/2 consistent gets. If you use an arraysize of 1000 - you would see about 58779/1000 consistent gets. That above link
has examples of this phenomena.

2) You did already? The second query used 810 logical IO's to perform its job. It included one physical IO using multi-block IO (we know it was multi-block IO because we did an index fast full scan)

Consistent gets are always block gets - single block gets. When we are talking "single block IO" and "multiblock IO" - we are talking about a physical IO phenomena. In this case - your index was almost entirely in cache and we didn't really do any physical
IO to speak of.
If you use an arraysize of 2 - you would see about 58779/2 consistent gets. If you use an arraysize of 1000 - you would see about 58779/1000 consistent gets

rajesh@10GR2> show arraysize;
arraysize 150
rajesh@10GR2>
rajesh@10GR2> set autotrace traceonly explain statistics;
rajesh@10GR2>
rajesh@10GR2> select owner,object_type,object_name
2  from t
3  order by owner,object_type,object_name;

Statistics
----------------------------------------------------------
0  recursive calls
0  db block gets
803  consistent gets
0  physical reads
58779  rows processed

rajesh@10GR2>
rajesh@10GR2> set autotrace off;
rajesh@10GR2>
rajesh@10GR2> select 58779/150 from dual;

58779/150
----------
391.86

Elapsed: 00:00:00.01
rajesh@10GR2>


Rows / array_size doesn't match with consistent gets.

rajesh@10GR2> set arraysize 2;
rajesh@10GR2>
rajesh@10GR2> select owner,object_type,object_name
2  from t
3  order by owner,object_type,object_name;

Statistics
----------------------------------------------------------
1  recursive calls
0  db block gets
29611  consistent gets
0  physical reads
0  redo size
58779  rows processed

rajesh@10GR2>
rajesh@10GR2>
rajesh@10GR2> set autotrace off
rajesh@10GR2>
rajesh@10GR2> select 58779/2 from dual;

58779/2
----------
29389.5

Elapsed: 00:00:00.03
rajesh@10GR2>


Rows / array_size pretty close with consistent gets.

rajesh@10GR2> set arraysize 1000;
rajesh@10GR2>
rajesh@10GR2>
rajesh@10GR2> select owner,object_type,object_name
2  from t
3  order by owner,object_type,object_name;

Statistics
----------------------------------------------------------
0  recursive calls
0  db block gets
473  consistent gets
0  physical reads
0  redo size
58779  rows processed

rajesh@10GR2>
rajesh@10GR2>
rajesh@10GR2> select 58779/1000 from dual;

58779/1000
----------
58.779

Elapsed: 00:00:00.03
rajesh@10GR2>


Rows / array_size doesn't match with consistent gets.

Tom:

I don't see Rows / array_size match with consistent gets. Is that wrong with Test cases?

Followup June 22, 2011 - 1pm Central time zone:

re-read the article I linked to. If you get an understanding of that - you'll get an understanding of these numbers.

It has to do with number of rows per block and how many times we have to read and RE-READ a block.

My math was "simplistic" - there is a diminishing return on larger and larger array fetch sizes - it kicks in at the point where your arraysize exceeds the number of rows on a block *in this particular case*.

Since there are 448 some odd blocks in the structure you are scanning - you'll obviously never go below that.

I should have written:

... - you would see about max( 58779/2, # blocks in structure) consistent gets. If you use an arraysize of 1000 - you would see
about max( 58779/1000, # blocks in structure) consistent gets. That above link has examples of this phenomena.

魔兽就是毒瘤,大家千万不要玩。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: