Oracle AutoTrace traceonly statistics(摘)
ops@DB10> set autotrace traceonly statistics
ops@DB10> select * from t;
no rows selected
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
995 bytes sent via SQL*Net to client
370 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
ops@DB10> insert into t select * from all_objects;
49933 rows created.
Statistics
----------------------------------------------------------
30139 recursive calls
6824 db block gets
100553 consistent gets
124 physical reads
5677972 redo size
922 bytes sent via SQL*Net to client
950 bytes received via SQL*Net from client
6 SQL*Net roundtrips to/from client
249 sorts (memory)
0 sorts (disk)
49933 rows processed
Recursive Calls
递归调用统计数据是指由于你需要执行其他SQL语句而必须执行的SQL.例如,如果你执行了一个插入
语句,它触发了一个运行某查询的触发器,它就是递归SQL.
(1)硬解析 如果递归调用次数开头很高,可以运行相应的查询,看看该统计数据是否仍然很高。
若不高,则表明递归SQL是由于硬解析造成的。
SQL> alter system flush shared_pool;
系统已更改。
SQL> select * from t;
已选择29457行。
Statistics
----------------------------------------------------------
1597 recursive calls
0 db block gets
2618 consistent gets
0 physical reads
0 redo size
2003435 bytes sent via SQL*Net to client
22096 bytes received via SQL*Net from client
1965 SQL*Net roundtrips to/from client
28 sorts (memory)
0 sorts (disk)
29457 rows processed
SQL> select * from t;
已选择29457行。
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2347 consistent gets
0 physical reads
0 redo size
2003435 bytes sent via SQL*Net to client
22096 bytes received via SQL*Net from client
1965 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
29457 rows processed
SQL>
如上所示,在此情况下递归SQL百分之百是由于首次分析查询的原因。为了得到被访问的对象、权限以及类似的东西,Oracle需要执行许多查询(因为我们刷新了共享池,这种信息的高速缓存)。递归调用SQL的次数降到了0,逻辑I/O
的数目(consistent gets)也迅速地下降,这些都是第二次运行时不需要进行硬解析的结果。
(2)PL/SQL函数调用
===================
如果SQL递归调用仍然很高,需要进一步研究。一种原因可能是你在SQL中调用了PL/SQL函数,此函数执行许多SQL语句,
或者引用了诸如USER这样的隐含使用了SQL的内建函数。所有在PL/SQL函数中执行的SQL都是为递归SQL.
create or replace function some_function return number
as
l_user varchar2(30) default user;
l_cnt number;
begin
select count(*) into l_cnt from dual;
return l_cnt;
end;
/
SQL> select object_name , some_function from t;
已选择29465行。
Statistics
----------------------------------------------------------
58930 recursive calls
0 db block gets
177202 consistent gets
0 physical reads
0 redo size
846166 bytes sent via SQL*Net to client
558 bytes received via SQL*Net from client
7 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
29465 rows processed
SQL>
已选择29465行。
58930 recursive calls
所查询的行每行两个
可行的解决方案是将PL/SQL子程序合并到查询中;例如,使用复杂的CASE语句或使用SELECT.上述查询可编写为:
select object_name, (select count(*) from dual) from t;
该sql不会导致任何递归SQL调用,并且执行同样的操作。
As for the USER local variable, I would recommend setting that once per session (using a
PL/SQL package), rather then referring to the USER pseudo column throughout the code. Every
time you declare a variable and default it to USER, that will be a recursive SQL call. It’s better
to have a package global variable that is defaulted to USER and just reference that instead.
(3)更改中产生的副作用
Recursive calls may also occur when you are doing a
modification and many side effects (triggers, function-based indexes, and so on) are happening.
Take the following, for example:
create trigger t_trigger before insert on t for each row
begin
for x in ( select *
from dual
where :new.x > (select count(*) from t1))
loop
raise_application_error( -20001, 'check failed' );
end loop;
end;
SQL> insert into t select 1 from all_users;
已创建15行。
SQL> set autotrace traceonly statistics
SQL> insert into t select 1 from all_users;
已创建15行。
Statistics
----------------------------------------------------------
16 recursive calls
15 db block gets
3400 consistent gets
0 physical reads
3480 redo size
625 bytes sent via SQL*Net to client
537 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
15 rows processed
在此例中,触发了触发器,然后对触发器处理的每一行执行此查询,这些产生了全部的递归调用。通常此类问题似乎不能避免,因为你需要完全消除触发器),但是,可以通过编写一个高效的触发器使递归次数最小化,即,尽可能减少递归SQL,并将SQL语句从触发器移到程序包中。
(4)空间请求 在响应对空间的请求时,由于磁盘排序或由于对需要扩展的表进行了大量更改,会出现大量的递归SQL操作。
对于本地管理的表空间来说,通常不会有这种问题,因为空间是位图方式在数据文件头部进行管理的
1、DB Block Gets(当前请求的块数目)
当前模式块意思就是在操作中正好提取的块数目,而不是在一致性读的情况下而产生的块数。
正常的情况下,一个查询提取的块是在查询开始的那个时间点上存在的数据块,当前块是在这个时刻存在的数据块,而不是在这个时间点之前或者之后的数据块数目。
2、Consistent Gets(数据请求总数在回滚段Buffer中的数据一致性读所需要的数据块)
这里的概念是在处理你这个操作的时候需要在一致性读状态上处理多少个块,这些块产生的主要原因是因为由于在你查询的过程中,由于其他会话对数据块进行操作,而对所要查询的块有了修改,但是由于我们的查询是在这些修改之前调用的,所以需要对回滚段中的数据块的前映像进行查询,以保证数据的一致性。这样就产生了一致性读。
3、Physical Reads(物理读)
就是从磁盘上读取数据块的数量,其产生的主要原因是:
1、 在数据库高速缓存中不存在这些块
2、 全表扫描
3、 磁盘排序
它们三者之间的关系大致可概括为:
逻辑读指的是Oracle从内存读到的数据块数量。一般来说是'consistent gets' + 'db block gets'。当在内存中找不到所需的数据块的话就需要从磁盘中获取,于是就产生了'phsical reads'。
当前的block是什么数据,那么读到的就是什么数据
比如数据是session自己产生的
在dml的时候读block中 数据 也必须是当前block的
而在查询中,block中数据如果是别人更改过的,就需要去回滚段中读取变化前的数据,这时产生consistent reads 这个叫一致读,也就是块处于 query mode 下
但是 consistent gets 是在query mode下的读,即使没有产生 consistent reads ,但是也叫 consistenet gets
db block gets : current mode , 不管这个块上的数据是否可能存在before image ,也就是说不管是否存在回滚中的数据可以回滚,只看见当前最新块的数据,即使别人正在更新,也看见别人更新状态的数据,比如dml的时候就不需要看见别人更改前的数据,而是看见正在更改的,当然同时,若操作相同数据则被lock住。也就是说一次查询中看见的数据可能不在同一个时间点上。
consistent gets : 看见的数据是查询开始的时间点的,所以若存在block在查询开始后发生了变化的情况,则必须产生 before image 然后读数据,这就是一致读的含义。
db block gets 仅仅表达,即使有回滚段内容也不用去产生before image
consistent get 仅仅表达,如果有回滚段内容并且block的变化的提交时间点晚于查询开始的时间点就要产生 before image ,但只有满足这个条件的时候才产生(回滚),并不是说一定要回滚 或者 是从回滚段获取来的数据
查询就是表示 consistent gets (query mode),因为查询要保证所获取的数据的时间点的一致性,所以叫一致读,即使是从当前 buffer 获得的数据,也叫 consistent gets ,这仅仅表达一种模式一种期望,并不表示真实的是从 当前buffer 获得还是从回滚段获取数据产生的 bufore image ,还有什么问题吗?
如果是 db block gets , current mode ,比如一个大的dml,当dml 开始更新一个非常大的表后,这个表更新的过程中,有一个进程去把该表末尾的一个记录更新了,然后这个大更新抵达该记录的时候会被阻塞的,若该进程事物提交,则大更新会覆盖该事务的更新,也就是说,这个大更新所看见的数据是当前的,不具有时间点的一致性,所以叫 current mode
把问题简单并粗略化:
db block gets 看作是 DML 的读取 ,其看到的数据可能不具有时间点的一致性。
consistent gets 是 select 这样的读取,无论是否来自回滚段的数据都是 consistents gets ,仅仅表示其看到的数据具有时间点上的一致性。
摘自:http://blog.sina.com.cn/s/blog_705c33110100wvwx.html
posted on 2014-03-02 00:04 pengdaijun 阅读(334) 评论(0) 收藏 举报
浙公网安备 33010602011771号