子游标过多问题
2019 年 4 月 1 日,在优化 emc 库 sql 的时候,发现一条 sql 下面有 60 多个子游标,其实不算太多,但是出于好奇还是想看看是什么原因导致了这么多的子游标无法共享的问题。之前处理过上千个子游标的问题,定位子游标无法共享原因的方法其实比较简单。
l 如果子游标没有那么多,比如这里就只有 60 多个,那么就直接查询 v$sql_shared_cursor 视图,子游标没有那么多,是可以肉眼观察分析结果的。
l 如果子游标很多,比如之前碰到的上千个,那么查询视图结果太多不好分析,此时可以借助 MOS 上拿来的存储过程,帮助我们分析。
select * from v$sql_shared_cursor where sql_id='bfd80zrdwa63f'; 这里采用直接查询视图定位原因的方法。
可以看到,子游标无法共享的原因在于 roll_invalid_mismatch 。 Oracle 在自动收集统计信息后,游标是否马上全部失效是由收集统计信息时的参数 no_invalid 控制的。该参数有 3 个值
TRUE: 不失效
FLASE: 马上失效
AUTO_INVALID:Oracle 自己决定什么时候失效。这个失效时间跟 sql 执行情况有关,也受另一个隐含参数的影响, _optimizer_invalidation_period 。
SQL> set line 200 SQL> col name for a30; SQL> col value for a10; SQL> select * from 2 (select 3 x.ksppinm name, 4 y.ksppstvl value, 5 y.ksppstdf isdefault, 6 decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, 7 decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 8 from |