oracle 物理读突然增加的原因_请教一个诡异的物理读比逻辑读还多的问题!!!!
本帖最后由 wxjzqym 于 2012-6-1 10:27 編輯
為了更好的理解物理讀和邏輯讀的關系,模擬了以下實驗:(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等待事件
希望各位能夠給予我解答,萬分感謝!
總結
以上是生活随笔為你收集整理的oracle 物理读突然增加的原因_请教一个诡异的物理读比逻辑读还多的问题!!!!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mac打开Finder快捷键
- 下一篇: Espresso浅析和使用