|
讲述一个我在实际工作中的oracle性能诊断的例子-------Oracle 碎片优化:
SELECT * FROM aaa where rownum<100
call count cpu elapsed disk query currentrows
------- ------ -------- ---------- -------------------- ---------- ----------
Parse 1 0.14 0.17 44 198 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 8 3.71 5.86 67489 68340 0 99
------- ------ -------- -------------------- ---------- ---------- ----------
total 10 3.85 6.03 67533 68538 0 99
从这上面看,确实产生了67533个物理读和68538个逻辑读。执行时间为6.03秒。从等待事件来看:
BINDS #39:
EXEC #39:c=0,e=88,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1422207486718
WAIT #39: nam='SQL*Net message to client'ela= 7 driver id=1650815232 #bytes=1 p3=0 obj#=206418 tim=1422207486810
WAIT #39: nam='SQL*Net more data to client'ela= 203 driver id=1650815232 #bytes=2002 p3=0 obj#=206418 tim=1422207487071
.......
确实存在大量的DB FILE SCATTERD READ。表里存在大量的碎片。找第一个SCATTERD READ的参数 file#=146 block#=92900,让客户执行alter system dump datafile 146 block min 92900 block max 92904。
获得的结果如下:
data_block_dump,data header at0x6000000000208e64
===============
tsiz: 0x1f98
hsiz: 0x4c
pbl: 0x6000000000208e64
bdba: 0x24816ae4 76543210
flag=--------
ntab=1
nrow=29
frre=0
fsbo=0x4c
fseo=0xf7
avsp=0x1f4c
tosp=0x1f4c
0xe ti[0] nrow=29 offs=0
0x12 ri[0] sfll=1
0x14 ri[1] sfll=2
0x16 ri[2] sfll=3
......
block_row_dump:
end_of_block_dump
里面全部是空块。建议客户做一个ALTER TABLE <table> MOVE;表重组后,发现原来10G的表只剩下650M了。再执行这个SQL,只有12个BUFFER GET了:
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
12 consistent gets
1 physical reads
0 redo size
18921 bytes sent via SQL*Net to client
558 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
从这个例子里可以看到优化的一个流程。遇到SQL 的问题,可以做10046和10053 事件,获取详细的信息,通过trace,分析原因,找到原因后,就可以解决问题,这里发现是碎片的问题,通过Move table 后,解决了碎片的问题,SQL 的性能得到提高。 |
|