在ArcSDE使用过程中,经常有用户抱怨ArcSDE的性能慢,那么除了常识性的ArcSDE知识来进行性能优化外,如果我们能够深入数据库,分析执行的每一个SQL语句,得到消耗时间最多的SQL语句,这样的话我们就可以有针对性的来对性能提供一个很好的而且有针对性的方向。
对跟踪Oracle trace文件其实并不复杂,ArcGIS也提供了相应的GP工具,如果不喜欢敲命令的朋友可以参考一下:
http://blog.csdn.net/linghe301/article/details/6946562
也可以使用PL/SQL来跟踪
但是,有时候去调试一般都没有那么多GUI客户端来帮助我们,所以还是掌握一个命令行的跟踪方法比较实用。
下面我们就介绍一下比较常用的在Session级别使用Oracle Trace方法来跟踪。
1:首先我们需要使用oracle的SYS用户来连接数据库
2:设置参数
- 修改时间格式:alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS';
- 设置TIMED_STATISTICS为True,设置在会话级: alter session set timed_statistics=True;
- 设置SQL_TRACE,在会话级:alter session set sql_trace=true;
SQL_TRACE是Oracle的一个非常强大的工具。主要用来检查数据库的异常情况,通过跟踪数据库的活动,找到有问题的语句。打开SQL_TRACE就可以逐步捕获任何一个会话的数据库活动,或者捕获整个数据库的活动,并将数据库活动记录成跟踪文件。每次使用完之后需要关闭跟踪,否则会降低系统的性能。
TIMED_STATISTICS指定与时间相关的统计量是否被收集。
3:获得session的SID和SERIAL#信息
在使用ArcGIS的时候,有人用服务连接,有人用直连,有人用ArcMap,有人用ArcCatalog,也有人用其他ArcGIS开发的客户端,那么在测试时,建议大家如果是自己开发的的程序可以转换成在Arcmap上进行测试,这样就可以来分析到底是客户端的问题还是数据库的问题,我们默认的ArcMap、ArcCatalog是绝对高效和无误的。
从上面可以获得相关的SID和SERIAL#信息
SQL> select SID,SERIAL#, USERNAME,MACHINE,PROGRAM,LOGON_TIME from v$session where username is not null;
SID SERIAL# USERNAME MACHINE PROGRAM LOGON_TIME
-------------------------------------------------------------------------------------------------------------------------------
1 68 15113 SYSTEM WORK\LISH plsqldev.exe 2013-3-6 10:38:39
2 73 6147 SDE WORK\LISH ArcMap.exe 2013-3-6 9:37:59
3 74 3645 SDE rhsde gsrvr@rhsde (TNS V1-V3) 2013-2-26 17:00:00
4 136 2856 SYSTEM WORK\LISH plsqldev.exe 2013-3-6 10:38:49
5 137 27 SDE rhsde gsrvr@rhsde (TNS V1-V3) 2013-3-6 11:04:29
6 195 3 SDE rhsde giomgr@rhsde (TNS V1-V3) 2013-2-16 7:54:59
7 rows selected
从上面可以获得相关的SID和SERIAL#信息
TIPs:上面我列出的信息比较全,但是实质内容是根据用户的连接session来获得SID和SERIAL#的内容,但是用户可以通过连接的客户端(ArcMap直连、PLSQL、gsrvr服务连接),连接终端的机器名,连接时间来确定相关信息。
4:开始跟踪,输入exec dbms_support.start_trace_in_session(&sid,&serial#,true,true)
TIPs:如果系统没有安装dbms_support包,可以执行$ORACLE_HOME/rdbms/admin/dbmssupp.sql进行安装
5.然后到ArcMap或ArcCatalog中进行你想跟踪的操作。
6.结束跟踪exec dbms_support.stop_trace_in_session(&sid,&serial#);
TIPs:最好是一步步的短操作,比如只测试加载数据,只测试放大数据,只测试编辑数据。
怎么得到trace文件,用户需要在服务器端的目录里面获得,我们可以直接进入服务目录,获得最近编辑时间(一般都是比较大的文件),但是并不是所有的系统都可以直接在服务器端随意访问的,用户也可以使用如下SQL语句,来获得trace文件的名字,到时候可以让DBA帮你拷贝出来。
SELECT d.VALUE
|| '/'
|| LOWER (RTRIM (i.INSTANCE, CHR (0)))
|| '_ora_'
|| p.spid
|| '.trc' trace_file_name
FROM (SELECT p.spid
FROM v$mystat m, v$session s, v$process p
WHERE m.statistic# = 1 AND s.SID = &SID AND p.addr = s.paddr) p,
(SELECT t.INSTANCE
FROM v$thread t, v$parameter v
WHERE v.NAME = 'thread'
AND (v.VALUE = 0 OR t.thread# = TO_NUMBER (v.VALUE))) i,
(SELECT VALUE
FROM v$parameter
WHERE NAME = 'user_dump_dest') d
那么,拿到了这个trace文件我们该怎么处理呢?一般情况下,如果没有足够的经验是不会直接打开那包含密密麻麻火星文的trc文件的,我们可以使用tkprof来格式化这个文件
如果你需要直接对该跟踪文件格式进行查看可以参考:http://blog.csdn.net/liufeng1980423/article/details/6074521
我们首先来看看tkprof的参数解释
那么格式化后的
sys参数,如果不指定默认值为yes.这个参数的含义是,输出文件中是否包含以SYS用户运行的sql语句。这个参数还是蛮有用的,我们执行sql语句的时候,后台经常会执行很多递归的语句,比如你输入了SELECT * FROM TEST;如果这个语句是硬解析的话,那么会产生很多递归的SQL,递归的去查询表的统计信息,列的统计信息,索引的统计信息等,当然递归的不止是这些。这些递归的sql都是以SYS用户运行的,如果你不希望看到这些递归SQL,那么就加上这个参数sys=no.
record参数,它指定的是一个路径下的文件,这个文件用来生成在跟踪文件中找到的所有的非递归SQL。比如你在SQLPLUS里执行了三条语句,select * from a;select * from b;select * from c;,那么如果你指定了这个参数如:record=c:\test.log,那么你用tkprof格式化跟踪文件后,这个test.log里就会记录这三个SQL。这个特性在有些时候还是满有用的,因为跟踪文件往往都会比较大,找起来会比较费劲,我们可以通过指定这个参数先大体了解下,跟踪文件里都有哪些非递归SQL。而且这个功能还有助于我们重演SQL语句(绑定变量的不可以)。
aggregate参数,它指定tkprof是否将同样文本内容的sql聚合处理,比如,你执行了十次select * from a,如果你指定这个参数为no(默认情况),那么产生的输出文件会有十个这样语句的执行信息,如果你指定的是yes,那么tkprof会把这十次的执行信息汇总显示。这个参数怎么指定就看你的需要了,个人觉得还是满有用的一个参数。
sort参数,这个参数是经常使用到的一个参数,它用来指定tkprof输出文件里sql语句按照什么排序,默认是按照执行的先后顺序排序的,我们可以指定它按照其他方式排序,比如磁盘读取数,CPU时间等。这个参数最经常用的方式是:sort=prsela,exeela,fchela,其实这三个值加起来就是响应时间,即按照响应时间排序。这里别产生误解,tkprof会根据prsela,exeela,fchela三个值的和进行排序,而不是像SQL语句似的一个个的排序。
print参数,它经常搭配sort参数一起使用,用来指定tkprof输出sql语句的数量。这两个参数搭配使用起来就比较妙,比如你想知道一个跟踪文件里响应时间排前十的SQL,那么你就可以sort=prsela,exeela,fchela print=10来搭配使用。
explain参数,这个参数的含义是为每一个SQL提供一个执行计划。使用的方法是explain=用户名/密码,其实原理很简单,就是通过你指定的用户名,密码登陆数据库,然后为每一个sql执行以下explain plan for sql,输出到plan_table里,最后添加到输出文件里。注意,由于explain plan for 命令要求执行操作的用户要对sql语句里包含的对象都有执行权限,如果包含视图,也要对视图基于的基础表有执行权限,否则产生不了执行计划。注意增加了这个参数后,执行tkprof会比较慢。
wait参数,指定输出文件中包含不包含等待事件,默认是包含的。一般都取默认值。
那么格式化后的
TKPROF: Release 11.2.0.1.0 - Development on 星期一 11月 7 11:37:34 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Trace file: c:\1.trc
Sort options: default
********************************************************************************
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
********************************************************************************
SQL ID: 3nkd3g3ju5ph1
Plan Hash: 2853959010
select obj#,type#,ctime,mtime,stime, status, dataobj#, flags, oid$, spare1,
spare2
from
obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null
and linkname is null and subname is null
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 7 0.00 0.00 0 0 0 0
Execute 129 0.03 0.04 0 0 0 0
Fetch 129 0.00 0.17 37 510 0 123
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 265 0.03 0.22 37 510 0 123
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 TABLE ACCESS BY INDEX ROWID OBJ$ (cr=3 pr=1 pw=0 time=0 us cost=4 size=83 card=1)
0 INDEX RANGE SCAN I_OBJ2 (cr=3 pr=1 pw=0 time=0 us cost=3 size=0 card=1)(object id 37)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 37 0.05 0.15
********************************************************************************
相关参数解释
其中比较有用的一个排序选项是fchela,即按照elapsed time fetching来对分析的结果排序(记住要设置初始化参数timed_statistics=true),生成的文件将把最消耗时间的sql放在最前面显示。另外一个有用的参数就是sys,这个参数设置为no可以阻止所有以sys用户执行的sql被显示出来,这样可以减少分析出来的文件的复杂度,便于查看。
CALL:每次SQL语句的处理都分成三个部分
Parse:这步将SQL语句转换成执行计划,包括检查是否有正确的授权和所需要用到的表、列以及其他引用到的对象是否存在。
Execute:这步是真正的由Oracle来执行语句。对于insert、update、delete操作,这步会修改数据,对于select操作,这步就只是确定选择的记录。
Fetch:返回查询语句中所获得的记录,这步只有select语句会被执行。
COUNT:这个语句被parse、execute、fetch的次数。
CPU:这个语句对于所有的parse、execute、fetch所消耗的cpu的时间,以秒为单位。
ELAPSED:这个语句所有消耗在parse、execute、fetch的总的时间。
DISK:从磁盘上的数据文件中物理读取的块的数量。一般来说更想知道的是正在从缓存中读取的数据而不是从磁盘上读取的数据。
QUERY:在一致性读模式下,所有parse、execute、fetch所获得的buffer的数量。一致性模式的buffer是用于给一个长时间运行的事务提供一个一致性读的快照,缓存实际上在头部存储了状态。
CURRENT:在current模式下所获得的buffer的数量。一般在current模式下执行insert、update、delete操作都会获取buffer。在current模式下如果在高速缓存区发现有新的缓存足够给当前的事务使用,则这些buffer都会被读入了缓存区中。
ROWS: 所有SQL语句返回的记录数目,但是不包括子查询中返回的记录数目。对于select语句,返回记录是在fetch这步,对于insert、update、delete操作,返回记录则是在execute这步。
其中比较有用的一个排序选项是fchela,即按照elapsed time fetching来对分析的结果排序(记住要设置初始化参数timed_statistics=true),生成的文件将把最消耗时间的sql放在最前面显示。另外一个有用的参数就是sys,这个参数设置为no可以阻止所有以sys用户执行的sql被显示出来,这样可以减少分析出来的文件的复杂度,便于查看。
比如:tkprof c:\1.trc sys=no sort=prsela,exeela,fchela print=10
上面就是不显示SYS用户的SQL,排列出前10个SQL语句,按照prsela,exela,fchela执行时间的总和顺序,如果这样的话,我们是不是可以把最耗时的SQL语句来分析,也可以获得一些导致性能下降的因素。
-------------------------------------------------------------------------------------------------------
版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
-------------------------------------------------------------------------------------------------------
版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
-------------------------------------------------------------------------------------------------------