Array Fetch Size研究Word下载.docx
《Array Fetch Size研究Word下载.docx》由会员分享,可在线阅读,更多相关《Array Fetch Size研究Word下载.docx(15页珍藏版)》请在冰豆网上搜索。
BANNER
----------------------------------------------------------------
OracleDatabase10gEnterpriseEditionRelease10.2.0.2.0-Prod
PL/SQLRelease10.2.0.2.0-Production
CORE
10.2.0.2.0
Production
TNSforLinux:
Version10.2.0.2.0-Production
NLSRTLVersion10.2.0.2.0-Production
oracle@orainst[orcl]:
~$uname-a
Linux2.4.21-50a6smp#1SMPWedOct318:
57:
25PDT2007i686i686i386GNU/Linux
~$cat/etc/redhat-release
RedHatEnterpriseLinuxWSrelease3(TaroonUpdate4)
top不同ArrayFetchSize下的统计输出
SQLPlus中可以自由的设定ArrayFetchSize的大小,因此我们的实验都是基于SQLPlus来完成的,实际上不管是什么类型客户端还是自己基于OCI写程序,都是能单独设置ArrayFetchSize的,SQLPlus设置方法为SETARRAYSIZEnumber,默认情况下的ArrayFetchSize大小为15,最大值允许设置的值是5000,可以通过SHOWARRAYSIZE来查看当前使用的值。
现在来建立一个测试表,然后设定不同ArrayFetchSize,在观察不同情况下查询输出的统计数据有什么样的区别。
首先建立测试数据:
--创建测试表
CREATETABLEtASSELECT*FROMall_objects;
Tablecreated.
--表建立完毕之后打开统计输出
SETAUTOTTRACESTATISTICS
SETTIMINGON
在表T上面我们没有建立任何的索引,现在我们查询表T中的一行数据,在查询一行数据时,查询的统计数据将不会受到ArrayFetchSize设定值的影响,这种情况下的consistentgets可以认为是对表T做一次全表扫描所必须要读取的块的数量,统计输出结果如下:
10
11
12
13
14
15
16
select*fromtwhereobject_id=100;
Elapsed:
00:
00:
00.01
Statistics
----------------------------------------------------------
1
recursivecalls
0
dbblockgets
147
consistentgets
physicalreads
redosize
1205
bytessentviaSQL*Nettoclient
384
bytesreceivedviaSQL*Netfromclient
2
SQL*Netroundtripsto/fromclient
sorts(memory)
sorts(disk)
rowsprocessed
接着尝试不同ArrayFetchSize值下的查询。
ArrayFetchSize为1时:
17
18
19
20
SETARRAYSIZE1
SELECT*FROMT;
11284rowsselected.
00.61
5712
1128755
62435
5643
11284
ArrayFetchSize为10时:
SETARRAYSIZE10
00.30
1257
555604
12792
1130
ArrayFetchSize为50时:
SETARRAYSIZE50
00.24
369
440923
2859
227
ArrayFetchSize为100时:
SETARRAYSIZE100
258
426572
1616
114
ArrayFetchSize为2500时:
SETARRAYSIZE2500
151
412856
428
6
为了对比的方便,我们将上面的数据汇总在下面的表格里面:
ArrayFetchSize
consistentgets
SQL*Netroundtrips
ElapsedTime
5712
5643
1257
1130
50
369
227
100
258
114
2500
151
表1:
不同ArrayFetchSize下统计数据对比
从上面的表中我们很容易就能看出来ArrayFetchSize对于consistentgets,SQL*Netroundtrips,ElapsedTime这三个参数的影响都还是比较大的。
文章的后面几个部分就来一个个的分析这些参数都是怎么被影响的。
top查询的工作过程
由于ArrayFetchSize的存在,客户端的动作可以分解成为下面的几个步骤:
1.向服务器请求ArrayFetchSize行数据
2.等待服务器服务器响应(此时服务器准备相应的数据)
3.从网络接收服务器传送的数据
4.将接收的数据在本地保存
5.检查是否取完所有数据,如果没有则转向第1步,否则完成查询
通过服务器端的10046trace可以大概看到整个过程,现在来重复一下ArrayFetchSize为1和100时的查询,并把查询产生的trace结果保存下来,得到trace的相关语句如下:
sqlplus"
orainst/hello"
<
<
EOF
SETAUTOTTRACESTATISTICS
SETTIMINGON
altersessionsettracefile_identifier='
arraysize01'
;
altersessionsetevents'
10046tracenamecontextforever,level12'
SETARRAYSIZE1
SELECT*FROMT;
类似的代码将SETARRAYSIZE1换成SETARRAYSIZE100再重复一次,这样可以在udump目录中看到两个名字中包含arraysize的trace文件,下面是我的运行结果:
/dumps-01/databases/orcl/udump
$ll-h
total1.8M
-rw-r--r--
1oracle
dba
1.6MMar
814:
35orcl_ora_27337_arraysize01.trc
64KMar
35orcl_ora_27341_arraysize100.trc
打开其中的名字为orcl_ora_27337_arraysize01.trc的文件,可以看到类似下面的代码:
PARSINGINCURSOR#6len=15dep=0uid=36oct=3lid=36tim=1238338811398144hv=1406298530ad='
3b4835fc'
SELECT*FROMT
ENDOFSTMT
PARSE#6:
c=0,e=25457,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=1238338811398132
BINDS#6:
EXEC#6:
c=0,e=62,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1238338811398383
WAIT#6:
nam='
SQL*Netmessagetoclient'
ela=2driverid=1650815232#bytes=1p3=0obj#=-1tim=1238338811398436
FETCH#6:
c=0,e=141,p=0,cr=4,cu=0,mis=0,r=1,dep=0,og=1,tim=1238338811398635
SQL*Netmessagefromclient'
ela=537driverid=1650815232#bytes=1p3=0obj#=-1tim=1238338811399242
ela=1driverid=1650815232#bytes=1p3=0obj#=-1tim=1238338811399324
......这里有几万条类似的记录......
c=0,e=46,p=0,cr=1,cu=0,mis=0,r=2,dep=0,og=1,tim=1238338812564076
ela=84driverid=1650815232#bytes=1p3=0obj#=-1tim=1238338812564204
ela=1driverid=1650815232#bytes=1p3=0obj#=-1tim=1238338812564252
c=0,e=48,p=0,cr=1,cu=0,mis=0,r=1,dep=0,og=1,tim=1238338812564291
ela=378driverid=1650815232#bytes=1p3=0obj#=-1tim=1238338812564744
***SESSIONID:
(30.30827)2010-03-0814:
35:
44.067
上面记录中显示的每次的FETCH操作就是服务器端准备数据的时间,等待消息为”SQL*Netmessagetoclient”的WAIT行就是向客户端传送数据并等待响应的过程,在ArrayFetchSize设置为100的那个trace文件中,我们还能看到类似于”SQL*Netmoredatatoclient”的等待时间,这个也是服务器还在向客户端传送数据的一个事件。
在这里,每一次的FETCH操作都会对应一次“向服务器请求ArrayFetchSize行数据”的操作(注意:
当ArrayFetchSize为1时SQLPlus会按照值为2的情况去取数据),只有最后一次的FETCH不一样,最后一次FECTH是为了确定已经没有数据可取的,因此在表T一共有11284行记录,所以对应的FETCH操作就共有11284/2+1=5643次,而ArrayFetchSize为100是FETCH的数量一共是roundup(11284/100)+1=114,这个数据我们可以通过运行下列命令看到:
#这个命令会处理生成的全部包含array字串的trace文件
$fornamein`lsorcl*array*.*`;
dotkprof$name$name.txt;
done
运行完了以后打开orcl_ora_27337_arraysize01.trc.txt可以看到下面的信息:
call
count
cpu
elapsed
disk
query
current
rows
-------------
------------------------------------------------
----------
Parse
1
0.00
0.02
0
0
Execute
Fetch
5643
0.21
0.25
5712
11284
total
5645
0.28
--中间省略了一部分数据--
Elapsedtimesincludewaitingonfollowingevents:
Eventwaitedon
Times
Max.Wait
TotalWaited
----------------------------------------
Waited
----------
------------
SQL*Netmessagetoclient