Oracle 嵌套块对PL/SQL过程的性能有影响吗?

Oracle 嵌套块对PL/SQL过程的性能有影响吗?,oracle,exception,plsql,Oracle,Exception,Plsql,在PL/SQL过程中,我经常将语句包装在一个块中(即begin…end),以便从该语句中隔离异常。例如,如果我正在执行一个可能引发“no_data_found”的select,我可以在知道异常是由该语句引发的情况下处理它,但让其他异常传播到过程的主异常处理程序 我想知道的是,这些额外的块是否会对性能产生影响。我知道引发异常会影响性能,所以我从不依赖异常作为控制流机制。但这座大楼本身有什么影响吗 例如,这两种方法的性能是否存在差异: procedure do_something as declar

在PL/SQL过程中,我经常将语句包装在一个块中(即begin…end),以便从该语句中隔离异常。例如,如果我正在执行一个可能引发“no_data_found”的select,我可以在知道异常是由该语句引发的情况下处理它,但让其他异常传播到过程的主异常处理程序

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

例如,这两种方法的性能是否存在差异:

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;
(我知道这段代码是荒谬的,但我希望它能说明我的意思!)

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

它们似乎不会:

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
当然,编译器可能正在删除冗余层,但我不确定它是否真的可以使用异常处理程序,因为这会影响结果


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

嗨,艾伦,没有完美的编码方式。这就是为什么我们都对自己的进步着迷。据我所知,你的编码风格是做事情的正确方式。我认为没有任何理由认为多个块会影响性能。我可能错了,因为我的名字不是Jesus,这是我写代码的方式。你是对的,但他问的是是否有性能影响,而不是这是否是正确的方法,即使有性能影响。我不知道,但这是一个有趣的问题。@pablomatico:你说得对。我不是问这是否正确——毕竟,什么是“正确”?我只是想问,无论块的内容如何,块的开始和结束本身是否会对性能产生影响。我只是想它可能会向堆栈中添加一个级别,或者类似的东西。它应该与调用过程相同,即向堆栈中添加一个级别。毕竟,过程是有名字的块,对吧?谢谢Alex,这正是我希望在这里说的:)