Skip to Main Content
  • Questions
  • How does Oracle know whether to check buffer cache or do I/O?

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Steven.

Asked: August 16, 2000 - 10:59 am UTC

Last updated: August 16, 2000 - 10:59 am UTC

Version: 8.0.5 EE on HP-UX

Viewed 1000+ times

You Asked

How does Oracle know whether a required block can be gotten from
the buffer cache or whether a physical I/O is required? For
example, some blocks of an index are in the buffer cache, and
a query's execution plan calls for an index range scan. How
does Oracle know whether or not the blocks in the "range" of
the range scan are in cache or not? Alternatively, if a full-
table scan is needed, will blocks already in cache be read
from cache, or will the entire table be accessed via physical
I/O? I apologize if I'm making this question more difficult
to understand than it actually is.

Thanks for the help you provide to the Oracle community - it's
greatly appreciated.

and Tom said...


Its a good question. Each block has a DBA (data block address) associated with it. We hash this DBA and store the blocks in lists according to their hashes. When you want a block -- we hash the dba -- look in that list and see if we can find it, if not read it and put it into the correct list.

When we do an indexed read - we get the DBA's from the index. We know the head DBA of the index (data dictionary tells us that) so we can find the top of the index. This head block will "point" to other DBA's and we walk the tree (look at the cache -- if found use it else read it, cache it, and then use it).

When fulling scanning -- we "synthesize" all of the DBA's we need for the table (we know what they are from the data dictionary by inspecting the extent layout of the table). We do much the same process -- goto the cache, if the synthesized DBA is not there -- read (in this case db_file_multiblock_read_count blocks) the block and cache it (cache THEM) and continue. The next N-1 reads should be cached as the next set of sequential DBA's should already be there.


You can observe this with autotrace by noting that a FULL SCAN does not always read from disk... for example, the second time around -- physical reads = 0

scott@8i> create table t1 as
2 select *
3 from all_objects
4 where rownum < 1000;

Table created.

scott@8i> alter table t1 cache;

Table altered.

scott@8i>
scott@8i> set autotrace on
scott@8i> select count(*) from t1;

COUNT(*)
----------
999


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'T1'




Statistics
----------------------------------------------------------
113 recursive calls
20 db block gets
24 consistent gets
15 physical reads
0 redo size
1089 bytes sent via SQL*Net to client
660 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
1 rows processed

scott@8i> select count(*) from t1;

COUNT(*)
----------
999


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'T1'




Statistics
----------------------------------------------------------
0 recursive calls
16 db block gets
15 consistent gets
0 physical reads
0 redo size
1090 bytes sent via SQL*Net to client
660 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1 rows processed

scott@8i> set autotrace off





Is this answer out of date? If it is, please let us know via a Comment

More to Explore

Performance

Get all the information about database performance in the Database Performance guide.