oracle 解析PL/SQL中的表达式-优化

ymzxtsji  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(113)

背景:
我试图评估PL/SQL中的一些代码,并使用它更新列。
示例表达式:

(5+1)  
(5+1)*3 / (case when 'some_text' = 'some_text' then 1 else 2 end)

这些表达式基本上是任何能在它们之间起作用的东西

SELECT ... FROM dual;

一个明显的简单答案是EXECUTE IMMEDIATE,它可以工作:

p_code := '(5+1)'
EXECUTE IMMEDIATE 'UPDATE some_table SET some_col = ' || p_code ||;

some_col列的值将被设置为5+1的求值,即6。这就是我想要的
问题是优化。
我有很多行要像这样更新,我想不出一种方法,除了一个接一个地循环我的记录,也就是慢慢地。
我不能让FORALL工作-它只适用于绑定变量。
你有其他的想法来处理这个问题吗?

ebdffaop

ebdffaop1#

少量的数据可以大大提高性能。即使您不得不“硬编码”您的XML,并且代码看起来很愚蠢,您仍然可以显著地提高性能。
批处理通过减少上下文切换、解析、权限检查、网络流量等开销来提高性能。如下面的代码所示,仅为2的批处理大小可以消除50%的开销。第一个PL/SQL块在0.48秒内一次计算1000个表达式。第二个PL/SQL块在0.23秒内一次计算两个1000个表达式。

--One expression at a time. Run times in seconds: 0.432, 0.523, 0.482
declare
    v_count number;
    v_expression varchar2(100);
begin
    --1000 expressions: 
    for i in 1 .. 1000 loop
        v_expression := '4 + ' ||i;
        execute immediate 'select ' || v_expression || ' from dual' into v_count;
    end loop;
end;
/

--Two expressions at a time: Run times in seconds: 0.241, 0.231, 0.230
declare
    v_count1 number;
    v_count2 number;
    v_expression1 varchar2(100);
    v_expression2 varchar2(100);
begin
    for i in 1 .. 500 loop
        v_expression1 := '4 + ' ||i;
        v_expression2 := '4 + ' ||i;
        execute immediate 'select ' || v_expression1 || ', ' || v_expression2 || ' from dual'
        into v_count1, v_count2;
    end loop;
end;
/

只需要去除这么多开销,并且它以1/N的谐波级数发生,因此您不需要非常大的批处理大小就可以获得接近最佳的效率。一次运行10个表达式可以删除90%,一次运行100个表达式可以删除99%,等等。选择一个小的数字,比如10,为你的代码向你的同事道歉,当表达式的数量不是10的倍数时,处理那些烦人的边缘情况,然后收工。

相关问题