oracle间断性走错执行计划

案例:

存储过程:sp_odm_ln_ar_smy



中间关联的表全部是左关联,关联了近30个表,且其中部分两三个关联的是嵌套子查询结果。

状况:

查询不出结果,最长时间执行了30多个小时,最后直接挂掉。该问题多次不间断出现,但未找到根本原因。


错误的执行计划:


正确的执行计划:


怀疑是统计信息的问题,所以手动收集该用户下所有表统计信息,

BEGIN
dbms_stats.gather_schema_stats(
ownname          => 'ODM',
options          => 'GATHER AUTO',
estimate_percent => dbms_stats.auto_sample_size,
method_opt       => 'for all columns size repeat',
degree           => 8
);
END;
当重新收集统计信息后,在执行该存储过程,恢复正常,1分钟内出结果。

至此,上述问题已经得到了暂时的解决。

最后我们在该存储过程前一个步骤的数据准备ETL里加入了手动收集统计信息代码。问题当时以为得到解决,但是后续仍然出现该状况。

现在比较纳闷的是已经重新收集统计信息了,为什么还是没有按照正确的执行计划走(这里我后面注意到信息收集完成时间实在48秒,而存储过程任务开始时间在47秒,从时间上看,可以认为存储过程开始时统计信息并未收集完成,我们统计信息收集的是整个用户,有可能最后收集的这个表我们存储过程不会用到,但是也有可能用到,这里就没办法判断存储过程所用到的表是否全部收集到了)。但是这里又没法把手动收集统计信息放在存储过程里,因为还有其他的存储过程。放哪都不合适,存储并不是等待所有数据准备完成后开始,而是其自身所需数据完成后就开始。

没办法,手动收集统计信息不行,然后只有想办法固定执行计划,通过SPM来固定执行计划。

开启自动捕获执行计划。

alter session set optimizer_capture_sql_plan_baselines=true;
但是查询dba_sql_plan_baselines发现,根本没有捕获到执行计划

SELECT signature,
       sql_handle,
       plan_name,
       origin,
       enabled,
       accepted,
       autopurge,
       t.fixed,
       t.sql_text,
       t.*
  FROM dba_sql_plan_baselines t;

然后改为手动捕获执行计划。

DECLARE
  my_plans PLS_INTEGER;
BEGIN
  my_plans := dbms_spm.load_plans_from_cursor_cache(sql_id => '8tn325hqykc39');
END;


然后查询dba_sql_plan_baselines,发现执行计划手动捕获成功。

再次执行存储过程,生成awrsqlrpt报告,发现执行计划是按照固定的执行的,且每次执行的sql_id都是固定的8tn325hqykc39,及先前手动捕获的sql_id。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值