【问题标题】:Do nested blocks have any performance impact in PL/SQL procedures?嵌套块对 PL/SQL 过程有任何性能影响吗?
【发布时间】:2014-05-15 00:52:41
【问题描述】:

在 PL/SQL 过程中,我经常将语句包装在一个块中(即开始...结束),以便我可以将异常与该语句隔离开来。例如,如果我正在执行可能引发“no_data_found”的选择,我可以在知道该语句引发异常的情况下处理它,但让其他异常传播到该过程的主要异常处理程序。

我想知道这些额外的块是否会对性能产生任何影响。我知道引发异常会对性能产生影响,所以我从不依赖异常作为控制流机制。但是区块本身有影响吗?

比如this的性能应该有什么区别:

procedure do_something
as
declare
  some_var number;
begin
  select some_value into some_var from some_table;
exception
when others then
  raise_application_error(-20000, 'Exception: ' || sqlerrm, true);
end do_something;

还有这个:

procedure do_something
as
declare
  some_var number;
begin
  begin
    select some_value into some_var from some_table;
  exception
  when no_data_found then
    some_var := -23; --some default value
  end;
exception
when others then
  raise_application_error(-20000, 'Exception: ' || sqlerrm, true);
end do_something;

(我知道这段代码很荒谬,但我希望它能说明我的意思!)

我真正关心的是没有引发异常时的性能 - 我可以接受出现异常时的性能下降。

【问题讨论】:

  • 嗨艾伦,没有完美的编码方式。这就是我们所有人都对我们的进步着迷的原因。根据我的说法,您的编码风格是做事的正确方式。我想不出多个块会影响性能的任何原因。我可能是错的,因为我的名字不是耶稣,这就是我编写代码的方式。
  • 你是对的 Veerender,但他问的是是否会对性能产生影响,而不是问这是否是正确的方法,即使有性能影响也是如此。我不知道,但这是一个有趣的问题..
  • @pablomatico:你是对的。我不是在问这是否正确——毕竟,什么是“正确的”?我只是在问,无论块的内容如何,​​开始和结束一个块本身是否会对性能产生影响。我只是想也许它会为堆栈增加一个级别,或者类似的东西。
  • 应该和调用过程一样,也就是给栈加一层。毕竟,过程是一种有名字的块,对吧?

标签: oracle exception plsql


【解决方案1】:

他们似乎没有:

set timing on
set serveroutput on

declare
  x number := 0;
begin
  dbms_output.put_line('No inner blocks');
  for i in 1..1000000 loop
    x := x + 1;
  end loop;
  dbms_output.put_line(x);
end;
/

anonymous block completed
Elapsed: 00:00:00.095
No inner blocks
1000000

在同一时间运行,每种方式都有一些变化,如:

declare
  x number := 0;
begin
  dbms_output.put_line('Nested inner blocks');
  for i in 1..1000000 loop
    begin
      begin
        begin
          begin
            x := x + 1;
          exception
            when others then
              raise;
          end;
        exception
          when others then
            raise;
        end;
      exception
        when others then
          raise;
      end;
    exception
      when others then
        raise;
    end;
  end loop;
  dbms_output.put_line(x);
end;
/

anonymous block completed
Elapsed: 00:00:00.090
Nested inner blocks
1000000

当然,编译器可能会删除冗余层,但我不确定它是否真的可以与那里的异常处理程序一起使用,因为它会影响结果。

我没有看到嵌套块的深度有任何限制 - 文档只是说“块可以嵌套”。您正在使用的模型,捕捉特定错误并让其他人传播,很好而且非常标准 - 尽管在您设计的示例中显然没有必要,但您知道这一点。

【讨论】:

  • 谢谢亚历克斯,正是我希望在这里 :)
猜你喜欢
  • 2020-07-27
  • 2011-11-12
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多