存储过程 入参为空的优化

o_range 2016-03-14 06:40:45
这是我现在的代码:

procedure SALE(para_s_rq in varchar2 ,
para_e_rq in varchar2,
para_reminder_id in varchar2,
para_buyer_id in varchar2,
para_goods_id in varchar2,
para_supplier_id in varchar2,
para_saler_id in varchar2,
para_orgid in integer,
para_p_cursor out t_cursor) is
begin
insert into A
select * from B
where b.date between(para_s_rq and para_e_rq)
(case when para_supplier_id is null or t.policy_supp_id =para_supplier_id then 1 else 0 end)=1
and (case when para_reminder_id is null or t.policy_reminder_id =para_reminder_id then 1 else 0 end)=1
and (case when para_orgid is null or b.org_id =para_orgid then 1 else 0 end)=1
and (case when para_goods_id is null or b.goodsid=para_goods_id then 1 else 0 end)=1
and (case when para_buyer_id is null or b.SUPPLYERID=para_buyer_id then 1 else 0 end)=1
and (case when para_reminder_id is null or t.policy_reminder_id=para_reminder_id then 1 else 0 end)=1
and (case when para_saler_id is null or b.salerid=para_saler_id then 1 else 0 end)=1
end SALE_REBATE_SETTLE;

后来单步执行,以及把语句摘出来运行发现,后面的条件 para is null or ...这类语句对效率的影响还是很大的~
求大神告诉如何进行优化~
...全文
358 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
o_range 2016-03-16
  • 打赏
  • 举报
回复
引用 7 楼 hidanger521 的回复:
空与非空写两个sql,通过if else判断,我一般会这么写,if else判断时间应该比拼在一起的sql效率要高吧。
关键是参数太多啊,要写多少个IF ELSE呢~~
流浪川 2016-03-16
  • 打赏
  • 举报
回复
空与非空写两个sql,通过if else判断,我一般会这么写,if else判断时间应该比拼在一起的sql效率要高吧。
o_range 2016-03-16
  • 打赏
  • 举报
回复
没有人遇到过这种问题么~~
o_range 2016-03-16
  • 打赏
  • 举报
回复
感谢各位的帮助,把case when 改成nvl()就快很多~
lhdz_bj 2016-03-16
  • 打赏
  • 举报
回复
嗯,应该还是执行计划发生了变化。 各表数据量是个什么情况,另外,带参数时的计划最好取下,也就是把参数当绑定变量取下计划。
o_range 2016-03-15
  • 打赏
  • 举报
回复
顶一下,防止沉贴~~~
o_range 2016-03-15
  • 打赏
  • 举报
回复
引用 3 楼 jdsnhan 的回复:
变量改为常量,贴出其执行计划



这是执行计划。。

我把那些使用入参的条件去掉后,SQL语句执行会很快~
o_range 2016-03-15
  • 打赏
  • 举报
回复
引用 2 楼 LHDZ_BJ 的回复:
优化不能听网上流传的那些条条框框的东西,条条框框的都有自己的场景和具体情况,因此,优化要活学活用,看具体的情况,因为楼主仅仅提供了部分SQL语句,在不了解数据环境和执行计划的前提下,不能很好的帮到楼主,如果可能,麻烦提供下我说的数据环境和执行计划。

select *
          from rebate_policy_sales_v t
          inner join base_sale_erp b
            on 
            (b.CREDATE between t.SECTION_BEGIN_DATE and t.SECTION_END_DATE)
           and b.supplyid = t.policy_supp_id
           and t.org_id=b.org_id
           left join (select b.dictdata_name, b.dictdata_value from tb_dictionary a, tb_dictionary_data b where a.id = b.dict_id and a.dict_name = 'RM_REBATE_MODEL_TYPE') d1
                on t.calculation_type = d1.dictdata_value
           left join (select b.dictdata_name, b.dictdata_value from tb_dictionary a, tb_dictionary_data b where a.id = b.dict_id and a.dict_name = 'RM_BASE_CALCULATION') d2
                on t.base_calculation = d2.dictdata_value
           left join (select b.dictdata_name, b.dictdata_value from tb_dictionary a, tb_dictionary_data b where a.id = b.dict_id and a.dict_name = 'RM_CALCULATION_METHOD') d3
                on t.calculation_method = d3.dictdata_value
           left join (select b.dictdata_name, b.dictdata_value from tb_dictionary a, tb_dictionary_data b where a.id = b.dict_id and a.dict_name = 'RM_CREDIT_TYPE') d4
                on t.credit_type = d4.dictdata_value
         where (case when '' is null or t.policy_supp_id ='' then 1 else 0 end)=1
           and (case when '' is null or t.policy_reminder_id ='' then 1 else 0 end)=1
           and (case when '' is null or b.org_id ='' then 1 else 0 end)=1
           and b.CREDATE between  to_date('2015-03-31' ,'yyyy-mm-dd hh24:mi:ss') and to_date('2016-03-31' ||' 23:59:59','yyyy-mm-dd hh24:mi:ss')
           and EXISTS(select 1 from base_goods_group_rl where group_id =t.goods_group_id  and is_active=1 AND GOODS_ID=B.GOODSID) 
           and EXISTS(select 1 from  base_customer_group_rl where group_id=t.custom_group_id and is_active=1 AND CUSTOMS_ID=B.CUSTOMID)
           and (case when '' is null or b.goodsid='' then 1 else 0 end)=1
           and (case when '' is null or b.SUPPLYERID='' then 1 else 0 end)=1
           and (case when '' is null or t.policy_reminder_id='' then 1 else 0 end)=1
           and (case when '' is null or b.salerid='' then 1 else 0 end)=1
           and t.detail_active = 1
           and t.rebate_policy_type = 3;
jdsnhan 2016-03-15
  • 打赏
  • 举报
回复
变量改为常量,贴出其执行计划
lhdz_bj 2016-03-15
  • 打赏
  • 举报
回复
优化不能听网上流传的那些条条框框的东西,条条框框的都有自己的场景和具体情况,因此,优化要活学活用,看具体的情况,因为楼主仅仅提供了部分SQL语句,在不了解数据环境和执行计划的前提下,不能很好的帮到楼主,如果可能,麻烦提供下我说的数据环境和执行计划。

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧