Home >Database >Mysql Tutorial >oracle 物理读,逻辑读的理解

oracle 物理读,逻辑读的理解

WBOY
WBOYOriginal
2016-06-07 15:45:431376browse

oracle 物理读,逻辑读的理解 / 2008-02-28 09:51:23/ 个人分类:学习 查看( 3120 ) /评论( 22 ) /评分( 23 / 11 ) 1.物理读(physical read) 当数据块第一次读取到,就会缓存到buffer cache 中,而第二次读取和修改该数据块时就在内存buffer cache 了 以下是例

oracle 物理读,逻辑读的理解

/  2008-02-28 09:51:23/ 个人分类:学习

查看( 3120 ) /评论( 22 ) / 评分( 23 / 11 )

1.物理读(physical read)

当数据块第一次读取到,就会缓存到buffer cache 中,而第二次读取和修改该数据块时就在内存buffer cache 了 以下是例子:

1.1  第一次读取:

C:\Documents and Settings\Paul Yi>sqlplus "/as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on Thu Feb 28 09:32:04 2008

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

SQL> set autotrace traceonly
SQL> select * from test;


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=4 Bytes=8)
   1    0   TABLE ACCESS (FULL) OF 'TEST' (Cost=2 Card=4 Bytes=8)

 


Statistics
----------------------------------------------------------
        175  recursive calls
          0  db block gets
         24  consistent gets
         9  physical reads             --9个物理读
          0  redo size
        373  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
          1  rows processed

1.2  第二次读取

SQL> select * from test;


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=4 Bytes=8)
   1    0   TABLE ACCESS (FULL) OF 'TEST' (Cost=2 Card=4 Bytes=8)

 


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads     --没有发生物理读了,直接从buffer cache 中读取了
          0  redo size
        373  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

1.3  数据块被重新读入buffer cache ,这种发生在

如果有新的数据需要被读入Buffer Cache中,而Buffer Cache又没有足够的空闲空间,Oracle就根据LRU算法将LRU链表中LRU端的数据置换出去。当这些数据被再次访问到时,需要重新从磁盘读入。

SQL> alter session set events 'immediate trace name flush_cache';--清空数据缓冲区

Session altered.

SQL> select * from test;


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=4 Bytes=8)
   1    0   TABLE ACCESS (FULL) OF 'TEST' (Cost=2 Card=4 Bytes=8)

 


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          6  physical reads   --又重新发生了物理读
          0  redo size
        373  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

2.逻辑读(buffer read)

逻辑读指的就是从(或者视图从)Buffer Cache中读取数据块。按照访问数据块的模式不同,可以分为即时读(Current Read)和一致性读(Consistent Read)。注意:逻辑IO只有逻辑读,没有逻辑写。

  • 即时读

即时读即读取数据块当前的最新数据。任何时候在Buffer Cache中都只有一份当前数据块。即时读通常发生在对数据进行修改、删除操作时。这时,进程会给数据加上行级锁,并且标识数据为“脏”数据。

SQL> select * from test for update;


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=4 Bytes=8)
   1    0   FOR UPDATE
   2    1     TABLE ACCESS (FULL) OF 'TEST' (Cost=2 Card=4 Bytes=8)

 


Statistics
----------------------------------------------------------
          0  recursive calls
         1  db block gets
         14  consistent gets
          0  physical reads
        252  redo size
        386  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

  • 一致性读

Oracle是一个多用户系统。当一个会话开始读取数据还未结束读取之前,可能会有其他会话修改它将要读取的数据。如果会话读取到修改后的数据,就会造成数据的不一致。一致性读就是为了保证数据的一致性。在Buffer Cache中的数据块上都会有最后一次修改数据块时的SCN。如果一个事务需要修改数据块中数据,会先在回滚段中保存一份修改前数据和SCN的数据块,然后再更新Buffer Cache中的数据块的数据及其SCN,并标识其为“脏”数据。当其他进程读取数据块时,会先比较数据块上的SCN和自己的SCN。如果数据块上的SCN小于等于进程本身的SCN,则直接读取数据块上的数据;如果数据块上的SCN大于进程本身的SCN,则会从回滚段中找出修改前的数据块读取数据。通常,普通查询都是一致性读。

下面这个例子帮助大家理解一下一致性读:

会话1中:

SQL> select * from test;

        ID
        ----------
          1000

SQL> update test set id=2000;

1 row updated.

会话2中:

SQL> set autotrace on
   SQL> select * from test;

        ID
       ----------
          1000


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=4 Bytes=8)
   1    0   TABLE ACCESS (FULL) OF 'TEST' (Cost=2 Card=4 Bytes=8)

 


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         9  consistent gets    没有事物做update时 是 7 consistent gets 说明多了2个  consistent gets    这2个是要从回滚段中获取的     
          0  physical reads
         52  redo size
        373  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn