oraclenumber型深度解析(oracle逻辑读是读哪里的数据)

技术怎样浅析Oracle的物理读 逻辑读 一致性读 当前模式读怎样浅析Oracle的物理读 逻辑读 一致性读 当前模式读,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简

如何分析Oracle的物理读取、逻辑读取和当前模式读取的一致性?针对这个问题,本文详细介绍了相应的分析和解决方法,希望能帮助更多想要解决这个问题的小伙伴找到更简单易行的方法。

Oracle物理阅读逻辑阅读一致性阅读当前模式阅读总结分析ORACLE数据库中有很多概念,比如物理阅读、逻辑阅读、一致性阅读、当前模式阅读等等。如果你不理解或混淆这些概念,无疑会成为你深入理解某些知识的障碍,但这些概念确实令人困惑。让我们总结学习这方面的一些知识点。我希望通过回顾他们的关系和特点对你有所帮助。

物理读(Physical Reads)

将数据块从磁盘读取到内存的操作称为物理读取。当这些数据块不存在于SGA的缓存缓冲区时,将发生物理读取。全表扫描和磁盘排序等操作也可能产生物理读取。原因是ORACLE数据库需要访问的数据块很多,有些数据块不在内存中,需要从磁盘读取。

逻辑读(Logical Reads)

概念1:逻辑读取指的是ORACLE从内存中读取的数据块数。一般来说,逻辑读取=数据库块获得一致的获取。

概念:逻辑读取是指从缓冲区缓存中读取数据块。根据访问数据块的不同模式,可以分为当前模式读取和一致读取。

这两个概念的本质是一样的,只是措辞不同。

一致性读(Consistant Get)

ORACLE是一个多用户系统。在一个会话开始读取数据并结束读取之前,其他会话可能会修改它将要读取的数据。如果会话读取修改的数据,将导致数据不一致。一致性读取是为了保证数据的一致性。在缓冲区缓存中的数据块上,有上次修改数据块时的SCN。如果事务需要修改数据块中的数据,它会先保存一份修改前的数据和回退段中带有SCN的数据块的副本,然后在Buffer Cache中更新数据块的数据和SCN,并将其标识为“脏”数据。当其他进程读取数据块时,它们首先将数据块上的SCN与进程自己的SCN进行比较。如果数据块上的SCN小于或等于进程本身的SCN,则直接读取数据块上的数据;如果数据块上的SCN大于进程本身的SCN,将从回退段找到修改前的数据块来读取数据。一般来说,普通查询都是一致读取。

当前模式读(DB Block Gets)

我个人认为当前的模式读取(db block gets)是最难理解的概念。通常,数据库块get可以理解为DML操作的结果。

当前模式读取(db块获取),即读取的数据块是当前最新的数据。缓冲区缓存中任何时候都只有一个当前数据块。当前读数通常发生在数据被修改或删除时。此时,流程将向数据添加行级锁,并将数据标识为“脏”数据。当前模式生成db块get,通常在DML操作期间生成,查询模式生成一致get,通常在查询期间生成。它们的总和一般称为逻辑读,逻辑读。

有趣的现象,在询问tom或者一些资料的时候,你会发现,Oracle 8i在SELECT查询中仍然可以看到db block get,但是在ORACLE 10及以上版本中,db block get一般在SELECT语句中是0。

理解了概念之后,如果你还有一些疑惑和困惑,我们就用实际的例子来理解这些概念吧。如下图:所示

SQLshowuserUSERis ' sys ' sqlcreatetabletest2 as3从dba_objects中选择*;表格已创建。sqlaltersessionsetSqL _ trace=true;系统改变了。SQLsetautotraceonSQLselectobject_type,n

bsp;count(1) from test

  2  group by object_type;
 
OBJECT_TYPE           COUNT(1)
------------------- ----------
EDITION                      1
INDEX PARTITION            264
CONSUMER GROUP              25
SEQUENCE                   223
TABLE PARTITION            240
SCHEDULE                     3
QUEUE                       35
RULE                         1
JAVA DATA                  328
...............................
...............................
 
43 rows selected.
 
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1435881708
 
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 75101 |   806K|   284   (2)| 00:00:04 |
|   1 |  HASH GROUP BY     |      | 75101 |   806K|   284   (2)| 00:00:04 |
|   2 |   TABLE ACCESS FULL| TEST | 75101 |   806K|   281   (1)| 00:00:04 |
---------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement (level=2)
 
 
Statistics
----------------------------------------------------------
         48  recursive calls
          0  db block gets
       1109  consistent gets
       1029  physical reads
          0  redo size
       1694  bytes sent via SQL*Net to client
        545  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         43  rows processed
 
SQL> select object_type, count(1) from test
  2  group by object_type;
 
OBJECT_TYPE           COUNT(1)
------------------- ----------
EDITION                      1
INDEX PARTITION            264
CONSUMER GROUP              25
SEQUENCE                   223
TABLE PARTITION            240
..............................
..............................
 
43 rows selected.
 
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1435881708
 
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 75101 |   806K|   284   (2)| 00:00:04 |
|   1 |  HASH GROUP BY     |      | 75101 |   806K|   284   (2)| 00:00:04 |
|   2 |   TABLE ACCESS FULL| TEST | 75101 |   806K|   281   (1)| 00:00:04 |
---------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement (level=2)
 
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1034  consistent gets
          0  physical reads
          0  redo size
       1694  bytes sent via SQL*Net to client
        545  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         43  rows processed
 
SQL> set autotrace off
SQL> alter session set sql_trace =false;
 
Session altered.
 
SQL> SELECT T.value
  2         || '/'
  3         || Lower(Rtrim(I.INSTANCE, Chr(0)))
  4         || '_ora_'
  5         || P.spid
  6         || '.trc' TRACE_FILE_NAME
  7  FROM   (SELECT P.spid
  8          FROM   v$mystat M,
  9                 v$session S,
 10                 v$process P
 11          WHERE  M.statistic# = 1
 12                 AND S.sid = M.sid
 13                 AND P.addr = S.paddr) P,
 14         (SELECT T.INSTANCE
 15          FROM   v$thread T,
 16                 v$parameter V
 17          WHERE  V.name = 'thread'
 18                 AND ( V.value = 0
 19                        OR T.thread# = To_number(V.value) )) I,
 20         (SELECT value
 21          FROM   v$parameter
 22          WHERE  name = 'user_dump_dest') T;
 
TRACE_FILE_NAME
--------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/gsp/gsp/trace/gsp_ora_24900.trc

 SQL语句第一次执行时,一致性读(consistent gets)为1109, 物理读(physical reads)为1029,当前模式读(db block gets)为0. 如果你再执行一次上面SQL语句,你会发现物理读(physical reads)会降低为0了,因为上一次查询,ORACLE已经将表test的所有数据块读取到buffer cache里面了。当然生产环境实际情况会复杂很多。

我们先用tkprof工具格式化一下trace文件,然后我们分析一下 out_24900.prf文件。

[oracle@DB-Server trace]$ tkprof gsp_ora_24900.trc out_24900.prf aggregate=no;

TKPROF: Release 11.2.0.1.0 - Development on Thu Sep 22 10:12:15 2016

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.

在分析之前,我们先了解一下一些概念、术语

count    = number of times OCI procedure was executed

cpu      = cpu time in seconds executing

elapsed  = elapsed time in seconds executing

disk     = number of physical reads of buffers from disk                   # 物理读

query    = number of buffers gotten for consistent read                    # 一致性读

current  = number of buffers gotten in current mode (usually for update)   # 当前模式读

rows     = number of rows processed by the fetch or execute call

 

 

call:每次SQL语句的处理都分成三个部分

 

    Parse:这步包括语法检查和语义检查(包括检查是否有正确的授权和所需要用到的表、列以及其他引用到的对象是否存在)、以及将SQL语句转换、生成执行计划等。

 

    Execute:这步是真正的由ORACLE来执行语句。对于insertupdatedelete操作,这步会修改数据,对于select操作,这步就只是确定选择的记录。

    Fetch:返回查询语句中所获得的记录,这步只有select语句会被执行。

 

count   : 这个语句被parseexecutefetch的次数。

cpu     :这个语句对于所有的parseexecutefetch所消耗的cpu的时间,以秒为单位。

elapsed :这个语句所有消耗在parseexecutefetch的总的时间。

disk    :从磁盘上的数据文件中物理读取的数据块的数量。

query   :在一致性读模式下,一致性读的数量。

current :在current模式下,即当前模式读下db blocks gets的数量。

rows    : 所有SQL语句返回的记录数目,但是不包括子查询中返回的记录数目。对于select语句,返回记录是在fetch这步,对于insertupdatedelete操作,返回记录则是在execute这步。 

如下截图所示(图1与图2本是连接在一起的,由于太长,分开截图,两张图片有相同部分),由于我们实验过程中,并没有采集统计信息,你会看到trac文件里面有一个动态采样(如果你在创建表,做一次统计信息收集,结果会有一些差别),另外,物理读和一致性读如下,跟上面的执行计划中的数据一致。

disk(物理读)      = 747+282 = 1029

query(一致性读)   = 1035+74 = 1109

继续分析格式化的prf文件,我们会看到第二次查询的query(一致性读)为1034, disk(物理读)为0上面例子,让我们了解了物理读、一致性读,那么接下来看看当前模式读(db block gets)的例子

SQL> create table t
  2  ( id  number(10)
  3  );
 
Table created.
 
SQL> set autotrace on;
SQL> insert into t
  2  values(1000);
 
1 row created.
 
 
Execution Plan
----------------------------------------------------------
---------------------------------------------------------------------------------
| Id  | Operation                | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |      |     1 |   100 |     1   (0)| 00:00:01 |
|   1 |  LOAD TABLE CONVENTIONAL | T    |       |       |            |          |
---------------------------------------------------------------------------------
 
Statistics
----------------------------------------------------------
          1  recursive calls
          7  db block gets
          1  consistent gets
          0  physical reads
        748  redo size
        836  bytes sent via SQL*Net to client
        783  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed
 
SQL> insert into t
  2  values(1001);
 
1 row created.
 
 
Execution Plan
----------------------------------------------------------
---------------------------------------------------------------------------------
| Id  | Operation                | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |      |     1 |   100 |     1   (0)| 00:00:01 |
|   1 |  LOAD TABLE CONVENTIONAL | T    |       |       |            |          |
---------------------------------------------------------------------------------
 
Statistics
----------------------------------------------------------
          1  recursive calls
          1  db block gets
          1  consistent gets
          0  physical reads
        308  redo size
        837  bytes sent via SQL*Net to client
        783  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed
 

一致性读如何计算呢?

关于一致性读如何计算呢? 我查了一下资料,一般一致性读consistent gets ~= numrows/arraysize + blocks ,确切的说是consistent reads计算 ~=ceil(获取行数(card)/arraysize)+used blocks, 而且这个不是绝对等于,而是约等于的关系。 但是这个不是官方资料,而是asktom和一些技术博客的介绍,我们来验证看看吧

 
SQL> exec dbms_stats.gather_table_stats(user, 'TEST');
 
PL/SQL procedure successfully completed.
 
SQL>
SQL> set autotrace traceonly stat
SQL> select * from test;
 
72271 rows selected.
 
 
Statistics
----------------------------------------------------------
        448  recursive calls
          0  db block gets
       5846  consistent gets
       1031  physical reads
          0  redo size
    8296071  bytes sent via SQL*Net to client
      53521  bytes received via SQL*Net from client
       4820  SQL*Net roundtrips to/from client
          3  sorts (memory)
          0  sorts (disk)
      72271  rows processed
SQL> /
 
72271 rows selected.
 
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       5789  consistent gets
          0  physical reads
          0  redo size
    8296071  bytes sent via SQL*Net to client
      53521  bytes received via SQL*Net from client
       4820  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      72271  rows processed
 
SQL> set autotrace off;
SQL> set serveroutput on;
SQL> exec show_space('TEST',USER);
Free Blocks.............................               0
Total Blocks............................           1,152
Total Bytes.............................       9,437,184
Total MBytes............................               9
Unused Blocks...........................             121
Unused Bytes............................         991,232
Last Used Ext FileId....................               1
Last Used Ext BlockId...................          89,344
Last Used Block.........................               7
 
PL/SQL procedure successfully completed.
 
SQL> show arraysize ;
arraysize 15
SQL> select ceil(72271/15) + 1152-121 from dual;
 
CEIL(72271/15)+1152-121
-----------------------
                   5850
 
SQL> SELECT COUNT(DISTINCT dbms_rowid.rowid_block_number(ROWID)) AS blocks FROM TEST;
 
    BLOCKS
----------
      1030
 
SQL> SELECT  ceil(72271/15) + 1030 FROM DUAL;
 
CEIL(72271/15)+1030
-------------------
               5849

不管是5849还是5850,都和5879 或5846有一点的出入?也就是说上面那个公式不能用等于号,关于这个,其实在https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:880343948514 里面,你会看到这里介绍的也是一个约等于关系,而不是一个绝对等于的关系。在这里我想深入一点,无奈知识有限。 从上面的公式, 我们可以看到一致性读跟arraysize的关系是蛮大的。那么我们来测试验证一下,先将araraysize调整为50

SQL> set autotrace off;
SQL> set arraysize 50
SQL> set autotrace traceonly stat;
SQL> select * from test;
 
72271 rows selected.
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       2456  consistent gets
          0  physical reads
          0  redo size
    7668743  bytes sent via SQL*Net to client
      16418  bytes received via SQL*Net from client
       1447  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      72271  rows processed
 
SQL>
SQL> SELECT  ceil(72271/50) + 1030 FROM DUAL;
CEIL(72271/50)+1030
-------------------
             2476
SQL>

如上所示,一致性读从5789降为了2456,有兴趣的可以做一下实验。另外,由于在Oracle中,取数据最后都是从buffer cache中取,所以每出现一个physical reads必然会出现一次 logical reads. 也就是说物理读(physical reads)一定小于逻辑读(logical reads=db block gets + consistent gets),也就是说物理读一定小于一致性读,但是也有物理读大于逻辑读的情况。

PURPOSE

In some circumstances, you can find that tkprof report shows more physical reads than logical reads, which isn't the current result as the physical reads are normally included in logical reads.

SCOPE & APPLICATION

This article will be useful for the DBA's and customers who are concerned by the tuning of Requests.

Why Physical reads are greater than Logical reads

Sometimes, you can find the following content in tkprof report:

· Physical Reads = Disk (total)

· Logical Reads = Query (total) + Current (total)

call

count

cpu

elapsed

disk

query

current

rows

-------

------

--------

----------

----------

----------

----------

----------

Parse

1

0.67

1.10

0

0

0

0

Execute

1

0.00

0.00

0

0

0

0

Fetch

2202

167.48

678.70

579441

283473

17418

33014

-------

------

--------

----------

----------

----------

----------

----------

total

2204

168.15

679.81

579441

283473

17418

33014

The 'disk' column is then greater than the 'query' + 'current' columns. This isn't usual.

To find the root cause of the problem, you must generate a 10046 event trace file level 8 and check for direct read waits in it.

In 10046 raw trace, you will find "direct path read" and "direct path write" waits like the example below:

WAIT #1: nam='direct path read' ela= 10076 p1=4 p2=29035 p3=1

with P1 = file#P2 = start block#P3 = num blocks

The "direct path read" waits account explains the difference between logical and physical reads.

In Oracle 9.2 and above, TKProf will print waits associated with each SQL statement in the output file.

Explanation:

The reason for more physical reads than logical reads is due to the number of direct reads block access. Direct path reads are generally used by Oracle when reading directly into PGA memory (as opposed to into the buffer cache).

They may happen on different actions:

· Sort IO on disk.

· Read by parallel Query Slaves when scanning is done.

· Blocks read by anticipation (readahead).

Such reads are done without loading blocks into the Buffer Cache. They can be single or multiblock reads.

Utilizing Direct Path Reads in this manner prevents the Oracle Buffer cache from beeing overloaded.

Oracle uses this optimisation when it considers that its not necessary to share the blocks between different sessions.

最后我们来看一个,热表上一致性读飙涨的案例,其实这个是Oracle 9i&10g编程艺术:深入数据库体系结构这本书籍里面的一个案例,我们在此重演一遍,希望能加深大家对一致性读的理解,首先准备测试数据环境

SQL> show user;
USER is "TEST"
SQL> create table t( x int);
 
Table created.
 
SQL> insert into t values(1);
 
1 row created.
 
SQL> commit;
 
Commit complete.
 
SQL> exec dbms_stats.gather_table_stats(user, 'T');
 
PL/SQL procedure successfully completed.
 
 
SQL> set autotrace on statistics;
SQL> select * from t;
 
         X
----------
         1
 
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        523  bytes sent via SQL*Net to client
        523  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的物理读 逻辑读 一致性读 当前模式读

如上所示,一般情况下一致性读为7,但是我们在一个会话窗口准备执行下面SQL,频繁修改表T

 
SQL> begin
  2   for i in 1 .. 100000
  3   loop
  4     update t set x=x+1;
  5     commit;
  6   end loop;
  7  end;
  8  /
 
PL/SQL procedure successfully completed.

在上面会话执行的同时,我们在另外一个会话窗口马上执行下面SQL,你会看到一致性读飙涨。

SQL> alter session set isolation_level=serializable;
 
Session altered.
 
SQL> set autotrace on statistics;
SQL> select * from t;
 
         X
----------
         1
 
 
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
      23681  consistent gets
          0  physical reads
          0  redo size
        523  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

将会话设置为使用SERIALIZABLE 隔离级别,这样无论在会话中运行多少次查询,都将得到事务开始时刻的查询结果。

Oracle 9i&10g编程艺术:深入数据库体系结构

在sql调优的时候,一个关键指标就是consistent gets,如果这个指标很低,一般认为sql语句执行还是很高效的,反之效率会很低。但是这个指标我们知之甚少,对于这个指标的计算方式我们也是懵懵懂懂。对于逻辑读来说,一般都是基于Logical Reads= Consistent Gets + DB Block Gets
如果我们知道logical reads是1000,我们可能错误地认为查询读取了1000*8k(约为8M)
看了博客https://viveklsharma.wordpress.com/2010/03/04/consistent-gets-myth/后,发现自己的认识是错误的,也按捺不住在本地测试了一把,受益匪浅。
首先我们来创建一个表,数据量为2000条。
n1@TEST11G> create table test_consistent_get  as select * from all_objects where rownum between 1 and 2000;
Table created.
然后收集统计信息
n1@TEST11G> exec dbms_stats.gather_table_stats(user,'TEST_CONSISTENT_GET');                               
PL/SQL procedure successfully completed.
查看相应的数据块为30个
n1@TEST11G> select num_rows,blocks,table_name,last_analyzed,global_stats from user_tables where table_name='TEST_CONSISTENT_GET';   
  NUM_ROWS     BLOCKS TABLE_NAME                     LAST_ANAL GLO
---------- ---------- ------------------------------ --------- ---
      2000         30 TEST_CONSISTENT_GET            20-APR-15 YES
n1@TEST11G> set autot trace
我们来看看执行计划,很明显走了一个全表扫描。但是我们需要关注的是统计信息中的consistent gets
n1@TEST11G> select * from test_consistent_get;                                                                                                                                         
Execution Plan
----------------------------------------------------------
Plan hash value: 1444268095
-----------------------------------------------------------------------------------------
| Id  | Operation         | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                     |  2000 |   164K|    10   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| TEST_CONSISTENT_GET |  2000 |   164K|    10   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        163  consistent gets
          0  physical reads
          0  redo size
     199754  bytes sent via SQL*Net to client
       1883  bytes received via SQL*Net from client
        135  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       2000  rows processed       
可以看到这个表占用的数据块为30,但是consistent gets却为163,很显然不是说这个全表扫描向cache里读入了163*8k的数据
我们可以通过rowid来得到对应的数据块和其中的数据情况
n1@TEST11G> select dbms_rowid.ROWID_BLOCK_NUMBER(rowid) blkno, count(*) cnt
    from test_consistent_get
    group by dbms_rowid.ROWID_BLOCK_NUMBER(rowid) order by 1;
     BLKNO        CNT
---------- ----------
    263827         88
    263828         84
    263829         81
    263830         76
    263831         81
    263832         80
    263833         82
    263834         77
    263835         73
    263836         78
    263837         79
    263838         79
    263839         81
    263841         82
    263842         77
    263843         81
    263844         80
    263845         81
    263846         78
    263847         78
    263848         76
    263849         78
    263850         78
    263851         76
    263852         81
    263853         15
26 rows selected.
可以通过rowid得到相关的数据块为26个。查看段头,发现对应的数据块是263826是不在上面的rowid对应的数据块范围内的。
n1@TEST11G> select header_block,blocks ,extents from dba_segments where segment_name='TEST_CONSISTENT_GET';
HEADER_BLOCK     BLOCKS    EXTENTS
------------ ---------- ----------
      263826         32          4
对应的区和数据块信息如下:
n1@TEST11G> select EXTENT_ID, FILE_ID, BLOCK_ID, BLOCKS from dba_extents where SEGMENT_NAME='TEST_CONSISTENT_GET';
 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         0          4     263824          8
         1          4     263832          8
         2          4     263840          8
         3          4     263848          8
下面的语句可以算出对于每个数据块对应的consistent gets的值。
n1@TEST11G> 
variable b1 number;
exec :b1:=15;
 compute sum of total_cnt on report
 compute sum of touch_cnt on report
 break on report
select blkno, total_cnt, final_cnt, rows_remaining,
case when rows_remaining=0 then touch_cnt+1 else touch_cnt end touch_cnt
from (
select blkno, total_cnt, final_cnt, rows_remaining,
case when total_cnt = final_cnt then ceil(final_cnt/:b1) else ceil(final_cnt/:b1)+1 end touch_cnt
from (
select blkno, cnt total_cnt, 
case when rownum=1 or lag(rows_remaining) over (order by blkno)=0 
                     then cnt else (cnt-(:b1-lag(rows_remaining) over (order by blkno))) end final_cnt,
rows_remaining 
from (
select blkno, cnt, rr, 
lead(rr) over(order by blkno) next_rr,
lead(blkno) over(order by blkno) next_blk,
ceil(rr/:b1) touch_cnt,
mod(rr,:b1) rows_remaining
from (
select dbms_rowid.ROWID_BLOCK_NUMBER(rowid) blkno, count(*) cnt, 
sum(count(*)) over(order by dbms_rowid.ROWID_BLOCK_NUMBER(rowid)) rr 
from test_consistent_get
group by dbms_rowid.ROWID_BLOCK_NUMBER(rowid) order by 1))));

     BLKNO  TOTAL_CNT  FINAL_CNT ROWS_REMAINING  TOUCH_CNT
---------- ---------- ---------- -------------- ----------
    263827         88         88             13          6
    263828         84         82              7          7
    263829         81         73             13          6
    263830         76         74             14          6
    263831         81         80              5          7
    263832         80         70             10          6
    263833         82         77              2          7
    263834         77         64              4          6
    263835         73         62              2          6
    263836         78         65              5          6
    263837         79         69              9          6
    263838         79         73             13          6
    263839         81         79              4          7
    263841         82         71             11          6
    263842         77         73             13          6
    263843         81         79              4          7
    263844         80         69              9          6
    263845         81         75              0          7
    263846         78         78              3          6
    263847         78         66              6          6
    263848         76         67              7          6
    263849         78         70             10          6
    263850         78         73             13          6
    263851         76         74             14          6
    263852         81         80              5          7
    263853         15          5              5          2
           ----------                           ----------
sum              2000                                  159
可以看到对于这个全表扫描的场景,consistent gets不是衡量对于cache的数据块数而是次数。
比如对于上面的数据块263827 ,数据条数为88条,arraysize为15,则可以简单说明一下是如何计算这个consistent gets值的。
对于数据块263827,放入PGA中,得到了15行,这个时候可以理解为consistent gets=1
对于数据块263827,再次从PGA中得到,得到了15行,这个时候consistent gets=2
依次类推
对于数据块263827,再次从PGA中得到,得到了13行,这个时候consistent gets=6
或者也可以基本按照这个公式来计算,数据行数/arraysize+数据块数=consistent gets
比如这个例子,2000/15+30 大概是163.3左右,所以163还是靠谱的。
对于arraysize未20,30,的情况下,相应的consistent gets也会减少。简单模拟一下。
n1@TEST11G> set arraysize 20  
n1@TEST11G> set autot trace exp stat
n1@TEST11G> select *from test_consistent_get;
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        128  consistent gets
          0  physical reads
          0  redo size
     195334  bytes sent via SQL*Net to client
       1509  bytes received via SQL*Net from client
        101  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       2000  rows processed
n1@TEST11G> set autot off
n1@TEST11G> select 2000/20+30 from dual;
2000/20+30
----------
       130
n1@TEST11G> set arraysize 30
n1@TEST11G> set autot trace  stat
n1@TEST11G> select *from test_consistent_get;
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         96  consistent gets
          0  physical reads
          0  redo size
     191044  bytes sent via SQL*Net to client
       1146  bytes received via SQL*Net from client
         68  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       2000  rows processed
n1@TEST11G> set autot off         
n1@TEST11G> select 2000/30+30 from dual;
2000/30+30
----------
96.6666667

关于怎样浅析Oracle的物理读 逻辑读 一致性读 当前模式读问题的解答就分享到这里了,希望

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/153555.html

(0)

相关推荐

  • ln2求导,证明ln2(2^4) + ln3

    技术ln2求导,证明ln2(2^4) + ln3我还是将原题的前因后果给你写一下吧,原理的第二问证明了ln(x)/x^2   ln2求导。。+lnn/(n^4)全部这类题一般是在高考题目中是最后一道大题的最后一问中出现,

    2021年10月22日
  • PostgreSQL的相似搜索插件有哪些

    技术PostgreSQL的相似搜索插件有哪些这篇文章主要介绍“PostgreSQL的相似搜索插件有哪些”,在日常操作中,相信很多人在PostgreSQL的相似搜索插件有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好

    攻略 2021年11月10日
  • 如何在NetBeans Java ME polish环境下开发BlackBerry应用

    技术如何在NetBeans Java ME polish环境下开发BlackBerry应用这期内容当中小编将会给大家带来有关如何在NetBeans Java ME polish环境下开发BlackBerry应用,文章内容

    攻略 2021年10月23日
  • 西汉建立时间,中国汉朝建立与公元多少年

    技术西汉建立时间,中国汉朝建立与公元多少年汉朝距今2216年西汉建立时间。因西汉建立是在公元前202年,而今年是公元2015年。即用公元前202年加上公元2015年,再减去1(因为没有公元0年),得到2216年。汉朝(前

    生活 2021年10月28日
  • 哪个平台买粉丝可靠?抖音经济刷粉丝网站!

    技术哪个平台买粉丝可靠?抖音经济刷粉丝网站!哪个平台买粉丝可靠?抖音经济刷粉丝网站!玩抖音的用户那么多,但不是所有人都把抖音玩好了。就看抖音粉丝这个数据,有的人的抖音粉丝几十上百万,抖音人气高涨;有的人的粉丝几十上百,抖

    测评 2021年11月11日
  • 箱线图怎么画,SPSS中如何绘制箱图

    技术箱线图怎么画,SPSS中如何绘制箱图箱线图主要包含六个数据节点,将一组数据从大到小排列,分别计算出它的上边缘箱线图怎么画、上四分位数、 中位数、下四分位数、下边缘,还有一个异常值。工具/原料电脑:组装台式机系统:wi

    生活 2021年10月27日