consistent read--一致性读--Logical read-逻辑读-current read当前读--物理读示例

来源:互联网 发布:买家淘宝客怎么用 编辑:程序博客网 时间:2024/06/05 09:07

各种数据读的解释:

数据块现在已经全部缓存到内存中了,我们从内存中读取块即可,不用再从磁盘中读取块了,自然就没有物理读。

Logical read:所谓逻辑读,就是从内存中读取数据块,包含current read 与 consistent read
current read:属于Oracle版本读取方式的一种机制,就是说当进行DML操作时,我们需要获取数据块最新的状态,只对最新状态进行操作,操作期间锁定数据行。
consistent read:当进行select查询时,我们需要获取查询那一刻数据块状态,不管查询了多长时间,我们只要查询那一瞬间的结果,如果查询期间数据块被修改,那么我们就去undo segment读取旧映像来呈现(如果旧映像被覆盖产生ora-01555错误)。
公式:logical read=db block gets(current read) + consistent gets(consistent read)
Physical read:所谓物理读,就是从磁盘中读取数据块

 一致性读实验:current read

假设从9点时发出一条查询,此查询语句运行了一分钟,那么查询的是9点时表内信息,如果在9时至9:00:30之间修改并提交了数据,查询语句扔查询结果仍是9点时的表内的数据。

实验如下 :在SESSION1中发出查询语句(增加条件延长查询语句运行时间)。在SESSION2中修改并提交。(需要在SESSION1查询语句运行期间进行)
SESSION1:
9:26:50 SQL> select * from test;
A
----------
1
2
3
4
5
6
7
16
18
19

10 rows selected

下面语句需要较长时间运行--大约一分钟,在此语句运行期间去SESSION2执行数据更新。

9:27:26 SQL> select * from test where a=7 and (select count(*) from dba_objects,dba_tables)>1 and (select count(*) from dba_objects,dba_tables)>2 ;
A
----------
7
9:28:05 SQL>

SESSION2:
9:27:13 SQL> select * from test;
 
A
----------
1
2
3
4
5
6
7
16
18
19
 
10 rows selected
9:27:14 SQL> update test set a=a+7 where a=7;
1 row updated
9:27:54 SQL> commit;
Commit complete
9:27:57
SQL> SELECT * FROM TEST;
A
----------
1
2
3
4
5
6
14
16
18
19
10 rows selected
9:28:50 SQL>

当前读-current read:

读取当前的 data block,最新的 data block,比如在update, delete的时候就总是current read。 因为要对最新的data block做更改,对过去更改没有实际意义。
执行过程描述:
session 1 开始了一个update 操作,通过consistent read(a=9) 获取了 数据块的id。
session 2 修改了 a=9 这一行的数据,变成了a=18
session 1 通过一个通过最开始查询a=9拿到的block id去以current read读取数据块,结果发现数据块不符合filter的条件a=9。所以 session 1没有更新。
session 1::
SQL> set time on
9:06:43 SQL> select a,DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) from test;
 
A          DBMS_ROWID.ROWID_BLOCK_NUMBER(
---------- ------------------------------
1                                     242
2                                     242
3                                     242
4                                     242
5                                     242
6                                     242
7                                     242
8                                     242
9                                     242
10                                    242

10 rows selected

执行UPDATE语句,加上的WHERE后条件可以使此语句执行长时间--大约1分钟--因为在此语句执行期间,在SESSION2执行了修改a=9数据的操作

所以此语句开始执行时,进行当前读,发现没有a=9的数据,所以返回0 rows updated

9:10:15 SQL> update test set a=a+1 where a=9 and (select count(*) from dba_objects,dba_tables)>1;
0 rows updated
9:10:40 SQL>
9:14:04 SQL> select * from test;
A
----------
1
2
3
4
5
6
7
8
18
10
10 rows selected
9:14:10 SQL>
 
SESSION2: 在会话1执行修改语句期间在会话2修改数据
SQL> set time on
9:07:48 SQL> update test set a=a+9 where a=9;
1 row updated
9:10:34 SQL> commit;
Commit complete
9:10:37
SQL>


logical read-----phicical read的概念及关系

SQL> create table test2 as select * from v$sysstat;
Table created

SQL> set autotrace traceonly

第一次执行查询操作,产生有物理读和逻辑读:

SQL> select count(*) from test2;
执行计划
----------------------------------------------------------
Plan hash value: 634289536
--------------------------------------------------------------------
| Id  | Operation          | Name  | Rows  | Cost (%CPU)| Time     |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |     1 |     4   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |       |     1 |            |          |
|   2 |   TABLE ACCESS FULL| TEST2 |   588 |     4   (0)| 00:00:01 |
--------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement (level=2)

统计信息
----------------------------------------------------------
          5  recursive calls
          0  db block gets
         15  consistent gets
          5  physical reads
          0  redo size
        424  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)

          1  rows processed

第二次使用相同语句时,查询时因为上次查询的数据已经加载到内存中,所以此次查询只有逻辑读,没有物理读。

SQL> select count(*) from test2;
执行计划
----------------------------------------------------------
Plan hash value: 634289536
--------------------------------------------------------------------
| Id  | Operation          | Name  | Rows  | Cost (%CPU)| Time     |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |     1 |     4   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |       |     1 |            |          |
|   2 |   TABLE ACCESS FULL| TEST2 |   588 |     4   (0)| 00:00:01 |
--------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement (level=2)
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads

          0  redo size
        424  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
原创粉丝点击