1.1.1.ordered by elapsed time: 记录了执行总和时间的top sql(请注意是监控范围内该sql的执行时间总和,而不是单次sql执行时间elapsedtime= cputimewait time)。
sql ordered by elapsed time
- resources reported for pl/sql code includes the resources used by all sql statements called by the code.
- % total db time is the elapsed time of the sql statement divided into the total database time multiplied by 100
elapsed time (s) | cpu time (s) | executions | elap per exec (s) | % total db time | sql id | sql module | sql text |
152,148 | 150,929 | 205,218 | 0.74 | 24.22 | | | update sys.aud$ set xid = :1 w... |
109,969 | 109,032 | 2,003 | 54.90 | 17.50 | | | declare job binary_integer := ... |
38,797 | 38,460 | 8,843 | 4.39 | 6.17 | | | declare job binary_integer := ... |
29,312 | 13,414 | 10 | 2931.15 | 4.67 | | | begin cs_slt_dscljg(:1, :2, :3... |
elapsed time(s): sql语句执行用总时长,此排序就是按照这个字段进行的。注意该时间不是单个sql跑的时间,而是监控范围内sql执行次数的总和时间。单位时间为秒。elapsedtime= cputimewait time
cpu time(s): 为sql语句执行时cpu占用时间总时长,此时间会小于等于elapsed time时间。单位时间为秒。
executions: sql语句在监控范围内的执行次数总计。
elap per exec(s):执行一次sql的平均时间。单位时间为秒。
% total db time: 为sql的elapsed time时间占总时间的百分比。
sql id:sql语句的id编号,点击之后就能导航到下边的sql详细列表中,点击ie的返回可以回到当前sql id的地方。
sql module: 显示该sql是用什么方式连接到数据库执行的,如果是用sql*plus或者pl/sql链接上来的那基本上都是有人在调试程序。一般用前台应用链接过来执行的sql该位置为空。
sql text:简单的sql提示,详细的需要点击sql id。
1.1.2.sql ordered by cpu time: 记录了执行占cpu时间总和时间最长的top sql(请注意是监控范围内该sql的执行占cpu时间总和,而不是单次sql执行时间)。
1.1.3.sql ordered by gets: 记录了执行占总buffer gets(逻辑io)的top sql(请注意是监控范围内该sql的执行占gets总和,而不是单次sql执行所占的gets).
1.1.4.sql ordered by reads:记录了执行占总磁盘物理读(物理io)的top sql(请注意是监控范围内该sql的执行占磁盘物理读总和,而不是单次sql执行所占的磁盘物理读)。
1.1.5.sql ordered by executions: 记录了按照sql的执行次数排序的top sql。该排序可以看出监控范围内的sql执行次数。
1.1.6.sql ordered by parse calls: 记录了sql的软解析次数的top sql。
说到软解析(soft prase)和硬解析(hard prase),就不能不说一下对sql的处理过程。当你发出一条sql语句交付oracle,在执行和获取结果前,oracle对此sql将进行几个步骤的处理过程:
1、语法检查(syntax check)
检查此sql的拼写是否语法。
2、语义检查(semantic check)
诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。
3、对sql语句进行解析(prase)
利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)。
4、执行sql,返回结果(execute and return)
其中,软、硬解析就发生在第三个过程里。
oracle利用内部的hash算法来取得该sql的hash值,然后在library cache里查找是否存在该hash值;
假设存在,则将此sql与cache中的进行比较;
假设“相同”,就将利用已有的解析树与执行计划,而省略了优化器的相关工作。这也就是软解析的过程。
诚然,如果上面的2个假设中任有一个不成立,那么优化器都将进行创建解析树、生成执行计划的动作。这个过程就叫硬解析。
创建解析树、生成执行计划对于sql的执行来说是开销昂贵的动作,所以,应当极力避免硬解析,尽量使用软解析。这就是在很多项目中,倡导开发人员对功能相同的要努力保持代码的一致性,以及要在程序中多使用绑定变量的原因。
/****************************************************/
大家都在说在sql中使用了bind var(绑定变量)会提高不少性能,那他到底是如何提高性能的呢?
使用了bind var能提高性能主要是因为这样做可以尽量避免不必要的硬分析(hard parse)而节约了时间,同时节约了大量的cpu资源。
当 一个client提交一条sql给oracle后,oracle首先会对其进行解析(parse),然后将解析结果提交给优化器(optimiser)来 进行优化而取得oracle认为的最优的query plan,然后再按照这个最优的plan来执行这个sql语句(当然在这之中如果只需要软解析的话会少部分步骤)。
但 是,当oracle接到client提交的sql后会首先在共享池(shared pool)里面去查找是否有之前已经解析好的与刚接到的这一个sql完全相同的sql(注意这里说的是完全相同,既要求语句上的字符级别的完全相同,又要 求涉及的对象也必须完全相同)。当发现有相同的以后解析器就不再对新的sql在此解析而直接用之前解析好的结果了。这里就节约了解析时间以及解析时候消耗 的cpu资源。尤其是在oltp中运行着的大量的短小sql,效果就会比较明显了。因为一条两条sql的时间可能不会有多少感觉,但是当量大了以后就会有 比较明显的感觉了。
上面说到了硬解析(hard parse),那这个hard parse到底是个啥呢?
parse主要分为三种:
1、hard parse (硬解析)
2、soft parse (软解析)
3、soft soft parse(好像有些资料中并没有将这个算在其中)
hard parse就是上面提到的对提交的sql完全重新从头进行解析(当在shared pool中找不到时候将会进行此操作),总共有一下5个执行步骤:
1:语法分析
2:权限与对象检查
3:在共享池中检查是否有完全相同的之前完全解析好的—如果存在,直接跳过4和5,运行sql(此时算soft parse)
4:选择执行计划
5:产生执行计划
soft parse就如果是在shared pool中找到了与之完全相同的sql解析好的结果后会跳过hard parse中的后面的两个步骤。
soft soft parse实际上是当设置了session_cursor_cache这个参数之后,cursor被直接cache在当前session的pga中的,在 解析的时候只需要对其语法分析、权限对象分析之后就可以转到pga中查找了,如果发现完全相同的cursor,就可以直接去取结果了,也就就是实现了 soft soft parse。
不过在计算解析次数的时候是只计算hard parse和soft parse的(其实soft soft parse好像也并不能算是做了parse ):
soft parse百分比计算:round(100*(1-:hprs/:prse),2) [hprs:硬解析次数;prse:解析次数]
parse比率计算: round(100*(1-prse/exec) ,2) [exec:执行次数]
软解析过多的意思就是说session_cursor_cache的数值有可能小了,一些频繁调用的sql在cache中找不到相同的cursor。
1.1.7.sql ordered by sharable memory: 记录了sql占用library cache的大小的top sql。
sharable mem (b):占用library cache的大小。单位是byte。
1.1.8.sql ordered by version count: 记录了sql的打开子游标的top sql。
在 硬解析的过程中,进程会一直持有library cach latch,直到硬解析结束。硬解析结束以后,会为该sql产生两个游标,一个是父游标,另一个是子游标。父游标里主要包含两种信息:sql文本以及优化 目标(optimizer goal)。父游标在第一次打开时被锁定,直到其他所有的session都关闭该游标后才被解锁。当父游标被锁定的时候是不能被交换出library cache的,只有在解锁以后才能被交换出library cache,这时该父游标对应的所有子游标也被交换出library cache。子游标包括游标所有的信息,比如具体的执行计划、绑定变量等。子游标随时可以被交换出library cache,当子游标被交换出library cache时,oracle可以利用父游标的信息重新构建出一个子游标来,这个过程叫reload。可以使用下面的方式来确定reload的比率:
select 100*sum(reloads)/sum(pins) reload_ratio from v$librarycache;
一 个父游标可以对应多个子游标。子游标具体的个数可以从v$sqlarea的version_count字段体现出来。而每个具体的子游标则全都在 v$sql里体现。当具体的绑定变量的值与上次的绑定变量的值有较大差异(比如上次执行的绑定变量的值的长度是6位,而这次执行的绑定变量的值的长度是 200位)时或者当sql语句完全相同,但是所引用的对象属于不同的schema时,都会创建一个新的子游标
1.1.9.sql ordered by cluster wait time: 记录了集群的等待时间的top sql
1.2. 其他员相关问题解析:1.2.1.load profile | per second | per transaction |
redo size: | 65,768.90 | 17,459.39 |
logical reads: | 31,757.56 | 8,430.54 |
block changes: | 271.06 | 71.96 |
physical reads: | 188.86 | 50.13 |
physical writes: | 11.90 | 3.16 |
user calls: | 197.15 | 52.34 |
parses: | 241.40 | 64.08 |
hard parses: | 1.90 | 0.50 |
sorts: | 12.46 | 3.31 |
logons: | 0.15 | 0.04 |
executes: | 313.88 | 83.32 |
transactions: | 3.77 | |
% blocks changed per read:
0.85
recursive call %:
95.92
rollback per transaction %:
30.79