sql优化,生产真实案例5

生产库查询存储过程执行慢

状况:
存储过程
在这里插入图片描述
点击画面中“x_ret_data”后面的 cursor查看数据,需要花费约20多秒

尝试使用plsql返回游标解析的方法测试速度也一样慢:

DECLARE
  v_cursor SYS_REFCURSOR;
  l_msg    VARCHAR2(400);
  l_code   VARCHAR2(400);

  TYPE v_tab_type IS TABLE OF temp20170320%ROWTYPE;
  v_tab v_tab_type;

BEGIN
  mes_cs_warehouse_approved.get_instoage_batch_dtail(p_orgid    => 329,
                                                     p_billtype => 1,
                                                     p_batchid  => '1299650',
                                                     p_cartonno => NULL,
                                                     p_barcode  => NULL,
                                                     x_ret_code => l_code,
                                                     x_ret_msg  => l_msg,
                                                     x_ret_data => v_cursor);

  FETCH v_cursor BULK COLLECT
    INTO v_tab;
  FOR i IN 1 .. v_tab.count
  LOOP
    dbms_output.put_line('字段1:' || v_tab(i).mitemname);
  END LOOP;


END;

分析:
Plsql里对当前会话做10046 trace

–开启10046

alter session set events '10046 trace name context forever,level 12';

–执行存储过程

DECLARE
  v_cursor SYS_REFCURSOR;
  l_msg    VARCHAR2(400);
  l_code   VARCHAR2(400);

  TYPE v_tab_type IS TABLE OF temp20170320%ROWTYPE;
  v_tab v_tab_type;

BEGIN
  mes_cs_warehouse_approved.get_instoage_batch_dtail(p_orgid    => 329,
                                           p_billtype => 1,
                                           p_batchid  => 1299650,
                                           p_cartonno => NULL,
                                           p_barcode  => '863882038348691',
                                           x_ret_code => l_code,
                                           x_ret_msg  => l_msg,
                                           x_ret_data => v_cursor);

  FETCH v_cursor BULK COLLECT
    INTO v_tab;
  FOR i IN 1 .. v_tab.count
  LOOP
    dbms_output.put_line('barcode:' || v_tab(i).barcode);
  END LOOP;

END;

–关闭10046

alter session set events '10046 trace name context off';

–查看trace文件路径

select tracefile from v$process where addr in (select paddr from v$session where sid in (select sid from v$mystat));

然后登陆到操作系统trace文件的目录对trace文件tkprof

tkprof xxx.trc xxx.txt

查看文本文件内容,其中下图中的执行计划显示fetch了200多万行

在这里插入图片描述
执行计划效率不佳

而如果将package中sql查询的那段SQL代码复制出来,代入查询条件却不慢,仅仅是执行存储过程慢,收集sql查询到的表的统计信息也没有作用。

在这里插入图片描述

处理:
存储过程传入参数p_batchid为varchar,与表字段类型number不一致,有时会导致索引用不上的问题,因此首先修改该参数类型。

修改参数类型后,执行速度依然没有改善,原因应该是该sql中is null or 这种语法太多,导致执行计划不正确,这种情况以前在其他程序里也出现过。

在这里插入图片描述
总结
对于PLSQL中的执行计划,分析时需要通过10046这种跟踪才能准确找的出来,后续遇到此类问题时可以作为参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dba任意

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值