oracle 物理读突然增加的原因_请教一个诡异的物理读比逻辑读还多的问题!!!!

博主通过实验发现一个SQL查询的物理读数量超过了逻辑读,对此感到疑惑。实验步骤包括创建表和索引,然后进行查询并观察执行计划和统计信息。结果显示,物理读16次,逻辑读4次,且等待事件为'db file scatter read'。通过10046 trace验证,发现物理读与表和索引的位图块对应。问题在于为何物理读会超过逻辑读,以及为何索引范围扫描会出现离散读。
摘要由CSDN通过智能技术生成

为了更好的理解物理读和逻辑读的关系,模拟了以下实验:(DB 10.2.0.1.0 32bit)

1.在scott用户下创建测试表和相关索引

create table tl(id int,name varchar2(100));

begin ... end;(使用存储过程向表中插入1000条记录)

create index tl_idx on tl(id);(在id字段上创建一个b-tree索引)

2.第一次执行该sql(这是为了去掉recursive calls 对实验的影响)

select * from tl where id=1;

3.在sys用户下刷新buffer cache中的block(这是为了当再次执行sql时发生物理读)

alter system flush buffer cache;

4.在scott用户下再次执行sql(同时打开autotrace以观察执行计划和统计信息)

set autot on

select * from tl where id=1;

ID NAME

---------- ----------

1

执行计划

----------------------------------------------------------

Plan hash value: 4160527729

--------------------------------------------------------------------------------------

| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |        |     1 |     3 |     2   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| TL     |     1 |     3 |     2   (0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | TL_IDX |     1 |       |     1   (0)| 00:00:01 |

--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("ID"=1)

统计信息

----------------------------------------------------------

0  recursive calls

0  db block gets

4  consistent gets

16  physical reads

0  redo size

460  bytes sent via SQL*Net to client

384  bytes received via SQL*Net from client

2  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

1  rows processed

从以上结果发现该sql消耗了16个物理读和4个逻辑读,在这里我就疑惑了,为什么物理读的个数会超过逻辑读?

以我的理解,在没有发生直接路径访问的情况下,每个物理读都会被读入buffer cache中,所以应该一个物理读就会对应一个逻辑读啊。

怀疑可能是autotrace显示信息不够正确。于是再次模拟这个实验,这次与上次稍微不同,在第4步时没有开启autotrace的功能

而是用10046 trace代替。可结果依然是16个物理读+4个逻辑读,且sql执行过程中的等待事件为db file scatter read,

这里又不理解了,为什么走索引时却发生了这个等待事件,10046  trace内容如下:

=====================

PARSING IN CURSOR #4 len=28 dep=0 uid=65 oct=3 lid=65 tim=5977017214 hv=1673619045 ad='334be8ac'

select * from tl where id=99

END OF STMT

PARSE #4:c=0,e=654,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=5977017211

BINDS #4:

EXEC #4:c=0,e=363,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=5977045113

WAIT #4: nam='SQL*Net message to client' ela= 3 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=5977045461

WAIT #4: nam='db file scattered read' ela= 19511 file#=4 block#=73 blocks=8 obj#=55362 tim=5977065349

WAIT #4: nam='db file scattered read' ela= 5828 file#=4 block#=65 blocks=8 obj#=55361 tim=5977071666

FETCH #4:c=0,e=26416,p=16,cr=3,cu=0,mis=0,r=1,dep=0,og=1,tim=5977072214

WAIT #4: nam='SQL*Net message from client' ela= 147 driver id=1111838976 #bytes=1 p3=0 obj#=55361 tim=5977072758

FETCH,tim=5977 #4:c=0,e=12,p=0,cr=1,cu=0,mis=0,r=0,dep=0,og=1073123

WAIT #4: nam='SQL*Net message to client' ela= 2 driver id=1111838976 #bytes=1 p3=0 obj#=55361 tim=5977073500

WAIT #4: nam='SQL*Net message from client' ela= 844 driver id=1111838976 #bytes=1 p3=0 obj#=55361 tim=5977074674

STAT #4 id=1 cnt=1 pid=0 pos=1 obj=55361 op='TABLE ACCESS BY INDEX ROWID TL (cr=4 pr=16 pw=0 time=26411 us)'

STAT #4 id=2 cnt=1 pid=1 pos=1 obj=55362 op='INDEX RANGE SCAN TL_IDX (cr=3 pr=8 pw=0 time=20023 us)'

WAIT #0: nam='SQL*Net message to client' ela= 1 driver id=1111838976 #bytes=1 p3=0 obj#=55361 tim=5977076054

从10046来看,发生了两次离散读,且每次都消耗了8个物理读,正好符合统计的数字,而文件号4的65和73正好是表和索引的位图块。

SQL> select extent_id,block_id,blocks from DBA_extents where segment_name='TL' and owner='SCOTT';

EXTENT_ID   BLOCK_ID     BLOCKS

---------- ---------- ----------

0         65          8

SQL> select extent_id,block_id,blocks from dba_extents where segment_name='TL_IDX' and owner='SCOTT';

EXTENT_ID   BLOCK_ID     BLOCKS

---------- ---------- ----------

0         73          8

总的来说就是两个问题困扰着我:

1.以上执行的sql中为什么物理读大于逻辑读

2.执行计划中的index range scan为什么会发生db file scatter read等待事件

希望各位能够给予我解答,万分感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值