为什么v$sql中的执行次数会被重置
2014-06-22 22:06
232 查看
这几天一直在观察生产环境中一个长时间执行的sql,我是用select * from v$sql where sql_id=*** 去观察的。因为这个sql是游标里面的语句,通过它执行的次数,我可以判断这个程序大概什么时候可以执行完毕。就在隔了一天,我再次用这个语句观察sql的执行次数时发现EXECUTIONS被重置了,数量比我前天观察到的小很多(在v$sql中通过sqlid只有一行数据),但是这个程序还在运行!我当时观察了 v$sql
的FIRST_LOAD_TIME,LAST_LOAD_TIME时间,前一个是sql开始执行的时间,这个没问题,后一个时间是凌晨时间,也就是说,凌晨的时候这个sql被重新加载了!我当时没想明白为什么会重新加载,今天看了篇有关父游标和子游标的文章后,才明白可能是sqlid在执行时,产生了子游标!!!!!
首先简单说明下父游标和子游标:
1. oracle是一个采用共享机制的数据库,如果sql能够共享,它是不会重新生成游标的(包括父游标和子游标);
2. 一个sql在首次被加载时,一定是产生一个父游标和一个子游标,V$SQL可以观察子游标,v$sqlarea可以观察父游标
SELECT T.FIRST_LOAD_TIME,
T.LAST_LOAD_TIME,
T.LAST_ACTIVE_TIME,
T.CHILD_NUMBER,
T.LOADS,
T.EXECUTIONS,
T.CHILD_ADDRESS
FROM V$SQL T
WHERE T.SQL_ID = 'gvhnpfk1ytyh3';
v$sqlarea中的EXECUTIONS是父游标下面全部子游标总共的执行次数(其实我应该从这里来观察总的执行次数)LOADED_VERSIONS表示有几个子游标。
所以通过V$SQL中的LAST_LOAD_TIME时间的变化,应该可以判断出来确实产生了新的子游标,从而导致EXECUTIONS被重置(这个时候的EXECUTIONS是新的子游标执行的次数)。解决了EXECUTIONS被重置的问题后,又引出了2个问题:1.为什么在V$SQL中我通过sqlid只看到一行记录;2.
是什么原因导致了正在执行的sql产生了新的子游标?
第一个问题,可能是因为前一个子游标因为空闲被置换出了内存;
第二个问题,可以通过一个视图来寻找答案:v$sql_shared_cursor
SELECT * FROM v$sql_shared_cursor t WHERE t.SQL_ID='gvhnpfk1ytyh3';
这个视图记录了每个子游标产生的原因(即sql不能共享的原因),通过帮助文档,我观察到其中有个原因很可能就是这次sql产生子游标的原因:STATS_ROW_MISMATCH(The existing statistics do not match the existing child cursor)很可能是定时的表分析使统计数据发生了变化,从而导致了新子游标的产生。。。希望明天去公司能够证实我的想法。。
的FIRST_LOAD_TIME,LAST_LOAD_TIME时间,前一个是sql开始执行的时间,这个没问题,后一个时间是凌晨时间,也就是说,凌晨的时候这个sql被重新加载了!我当时没想明白为什么会重新加载,今天看了篇有关父游标和子游标的文章后,才明白可能是sqlid在执行时,产生了子游标!!!!!
首先简单说明下父游标和子游标:
1. oracle是一个采用共享机制的数据库,如果sql能够共享,它是不会重新生成游标的(包括父游标和子游标);
2. 一个sql在首次被加载时,一定是产生一个父游标和一个子游标,V$SQL可以观察子游标,v$sqlarea可以观察父游标
SELECT T.FIRST_LOAD_TIME,
T.LAST_LOAD_TIME,
T.LAST_ACTIVE_TIME,
T.CHILD_NUMBER,
T.LOADS,
T.EXECUTIONS,
T.CHILD_ADDRESS
FROM V$SQL T
WHERE T.SQL_ID = 'gvhnpfk1ytyh3';
SELECT T.SQL_ID, T.EXECUTIONS, T.LOADED_VERSIONS, T.LOADS, T.ADDRESS FROM V$SQLAREA T WHERE T.SQL_ID = 'gvhnpfk1ytyh3';V$SQL中的FIRST_LOAD_TIME是表示父游标的加载时间,LAST_LOAD_TIME表示对应子游标的加载时间,child_number表示子游标的编号(从0开始);
v$sqlarea中的EXECUTIONS是父游标下面全部子游标总共的执行次数(其实我应该从这里来观察总的执行次数)LOADED_VERSIONS表示有几个子游标。
所以通过V$SQL中的LAST_LOAD_TIME时间的变化,应该可以判断出来确实产生了新的子游标,从而导致EXECUTIONS被重置(这个时候的EXECUTIONS是新的子游标执行的次数)。解决了EXECUTIONS被重置的问题后,又引出了2个问题:1.为什么在V$SQL中我通过sqlid只看到一行记录;2.
是什么原因导致了正在执行的sql产生了新的子游标?
第一个问题,可能是因为前一个子游标因为空闲被置换出了内存;
第二个问题,可以通过一个视图来寻找答案:v$sql_shared_cursor
SELECT * FROM v$sql_shared_cursor t WHERE t.SQL_ID='gvhnpfk1ytyh3';
这个视图记录了每个子游标产生的原因(即sql不能共享的原因),通过帮助文档,我观察到其中有个原因很可能就是这次sql产生子游标的原因:STATS_ROW_MISMATCH(The existing statistics do not match the existing child cursor)很可能是定时的表分析使统计数据发生了变化,从而导致了新子游标的产生。。。希望明天去公司能够证实我的想法。。
相关文章推荐
- 为什么v$sql中的执行次数会被重置(续)
- 请教:PL/SQL中执行to_date(to_char(a.lastupdatedate, 'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD HH24:MI:SS') ,上午12点整为什么格式化出来没有时分秒?
- 简单骗过DataContext,统计Linq to SQL执行查询的次数
- v$sql_plan看到不执行计划
- sql server性能分析--执行sql次数和逻辑次数
- 使用mybatis执行sql的时候为什么会出现Parameter index out of range (1 > number of parameters, which is 0)?
- 为什么ASP中执行动态SQL总报错误信息?提示语句语法错误
- 查看PKG是否在内存并统计PKG里SQL执行次数
- sql server执行计划重用次数
- oracle 抓出cup执行时间最多,执行次数最多的sql语句
- sql server性能分析--执行sql次数和逻辑次数
- 在access中执行SQL,SQL中包含IIF,取出来的结果集字符串被截断了,请教各位大侠,这个是为什么呀?谢谢!
- SQL 2005 统计sql执行的次数和时间
- sql server性能分析--执行sql次数和逻辑次数
- sql server执行sql次数和逻辑次数
- sql server性能分析--执行sql次数和逻辑次数
- Oracle 查看当前执行IO次数最多的SQL
- 为什么ubuntu里在rc.local里设置的export在它执行完后会被重置?
- 格式化v$sql_plan查看实际执行计划
- SQL 查看SQL语句执行效率 编译时间 执行时间 逻辑读取总次数