2014-12-25 Created By 鲍新建
一、摘要
在ORACLE数据库应用调优中,一个SQL的执行次数/频率也是常常需要关注的,因为某个SQL执行太频繁,要么是由于应用设计有缺陷,需要在业务逻辑上做出优化处理,要么是业务特殊性所导致。
如果执行频繁的SQL,往往容易遭遇一些并发性的问题。
那么如何查看ORACLE数据库某个SQL的执行频率/次数,潇湘隐者同学整理如下,借花献佛了 :)
方法1: 通过查询V$SQLAREA或V$SQL的EXECUTIONS来查看SQL的执行次数;
方法2:通过DBA_HIST_SQLSTAT关联DBA_HIST_SNAPSHOT找出某些SQL的执行次数;
方法3:AWR报告查看某个SQL的执行次数;
二、三种方法解析
1. 通过查询V$SQLAREA或V$SQL的EXECUTIONS来查看SQL的执行次数
(1). 缺点
但是这个值的有效性需要结合FIRST_LOAD_TIME来判断,因为V$SQLAREA或V$SQL中不保存历史数据,
具有一定的时效性,所以如果要查询很久以前的某个SQL执行次数是办不到的。
(2). 关于V$SQLAREA 栏位介绍
FIRST_LOAD_TIME VARCHAR2(19) Timestamp of the parent creation time
EXECUTIONS NUMBER Total number of executions, totalled over all the child cursors
(3). 如何查询
SELECT SQL_ID, SQL_TEXT,FIRST_LOAD_TIME, EXECUTIONS FROM V$SQLAREA WHERE SQL_ID = ' 497wh6n7hu14f '
(4). 总结
如果此时清空共享池,那么你会发现V$SQLAREA中对应的SQL的EXECUTIONS次数清零了。
如果要查看某个时间段该SQL语句执行了多少次,那么必须在这两个时间段执行上面SQL语句,两次EXECUTIONS的差值表示这段时间内SQL语句的执行次数。
EXECUTIONS是全局的,往往不能查看某个会话或用户执行了多少次。这也是其局限性之一。
2. 通过DBA_HIST_SQLSTAT关联DBA_HIST_SNAPSHOT找出某些SQL的执行次数。
(1). 缺点
但是部分快照如果没有捕获到有些SQL。这样也就无法通过下面SQL语句查看执行次数。
也是就说这种方法是有缺陷的。执行越频繁的语句,也越容易被SNAPSHOT抓取到.
(2). 执行语法
SELECT M.SQL_ID, TO_CHAR (N.BEGIN_INTERVAL_TIME, ' YYYY-MM-DD ' ) " DATETIME ", SUM (M.EXECUTIONS_DELTA) EXECUTIONS FROM DBA_HIST_SQLSTAT M, DBA_HIST_SNAPSHOT N WHERE M.SNAP_ID = N.SNAP_ID AND M.DBID = N.DBID AND M.INSTANCE_NUMBER = N.INSTANCE_NUMBER AND M.INSTANCE_NUMBER = 1 AND TO_CHAR (N.BEGIN_INTERVAL_TIME, ' YYYY-MM-DD ' ) = ' 2014-12-25 ' AND M.SQL_ID = ' 497wh6n7hu14f ' GROUP BY M.SQL_ID, TO_CHAR (N.BEGIN_INTERVAL_TIME, ' YYYY-MM-DD ' ) ORDER BY M.SQL_ID
3. AWR报告查看某个SQL的执行次数,同上面一样,AWR报告也受SNAPSHOT影响。不一定捕获了你需要查询的SQL
4. 查看当前数据库执行次数最多的SQL,例如,查询执行最频繁的TOP 15的SQL语句。
SELECT SQL_TEXT, EXECUTIONS FROM ( SELECT SQL_TEXT, EXECUTIONS, RANK () OVER ( ORDER BY EXECUTIONS DESC ) EXEC_RANK FROM V$SQLAREA) WHERE EXEC_RANK <= 15 ;
一、摘要
在做咨询时,经查遇到以前SQL的运行情况,和查询使用的条件
查询绑定变量时,有硬解析和软解析之分,如果是软解析,变量的值就很难找到了
查询绑定变量的几个视图如下:
- 查询v$sql视图
- 查询v$sql_bind_capture
- 查询dba_hist_sqlbind
- 查询wrh$sqlstat
二、查询v$sql视图
1. 查询bind_data
select sql_id, sql_text, bind_data, hash_value
from v$sql
where sql_text l
ike
'
%select * from test where id1%
';
它的记录频率受_cursor_bind_capture_interval 隐含参数控制,默认值900,表示每900秒记录一次绑定值,可以通过alter system set "_cursor_bind_capture_interval"=10;
2. bind_data
select dbms_sqltune.extract_binds(bind_data) bind
from v$sql
where sql_text like
'
%FROM TEST11%
';
此时查询到的data值得形式是这样的:BEDA0B2002004F8482D10065FFFF0F000000003132303431313,需要通过dbms_sqltune.extract_binds进行转换
三、查询v$sql_bind_capture
通过v$sql_bind_capture视图,可以查看绑定变量,但是这个视图不太给力,只能捕获最后一次记录的绑定变量值。
而且两次捕获的间隔有一个隐含参数控制。默认是900秒,才会重新开始捕获。在900内,绑定变量值的改变不会反应在这个视图中。
10G以后可以通过如下方法查看AWR报告里记录的SQL的绑定变量值。
select value_string
from v$sql_bind_capture
where sql_id
=
'
abhf6n1xqgrr0
';
四、查询dba_hist_sqlbind
10G以后可以通过如下方法查看AWR报告里记录的SQL的绑定变量值。
select snap_id, name, position, value_string,last_captured,WAS_CAPTURED
from dba_hist_sqlbind
where sql_id
=
'
576c1s91gua19
'
and snap_id
=
'
20433
'
;
--
--------snap_id, AWR报告的快照ID。
--
--------name, 绑定变量的名称
--
--------position,绑定值在SQL语句中的位置,以1,2,3进行标注
--
--------value_string,就是绑定变量值
--
--------last_captured,最后捕获到的时间
--
--------was_captured,是否绑定被捕获,where子句前面的绑定不进行捕获。
dba_hist_sqlbind视图强大的地方在于,它记录了每个AWR报告里的SQL的绑定变量值,当然这个绑定变量值也是AWR生成的时候从v$sql_bind_capture采样获得的。
通过这个视图,我们能够获得比较多的绑定变量值,对于我们排查问题,这些值一般足够了。
还有一个需要注意的地方是,这两个视图中记录的绑定变量只对where条件后面的绑定进行捕获,这点需要使用的时候注意。
查询 dba_hist_sqlbind value_string列
dba_hist_sqlbind是视图v$sql_bind_capture历史快照
五、查询wrh$sqlstat
两外一个查询绑定变量的视图
select dbms_sqltune.extract_bind(bind_data,
1
).value_string
from
wrh$_sqlstat
where sql_id
=
'
88dz0k2qvg876
'
--
--------根据绑定变量的多少增加dbms_sqltune.extract_bind(bind_data, 2).value_string等
参考:aaaaaaaa2000 - http://blog.csdn.net/aaaaaaaa2000/article/details/7401110
参考:潇湘隐者 - http://www.cnblogs.com/kerrycode/p/4111746.html (略加排版)