Performance de objetos PL/SQL compilados para debbuging
Autor: Fabio Prado | Publicado: 2017-05-03T21:00:00-03:00



&nbsp;Olá pessoal,


&nbsp; &nbsp; &nbsp;Todo DBA ou Desenvolvedor que programa em PL/SQL há algum tempo ou participou de algum curso sobre essa linguagem, provavelmente sabe que existem 2 modos de compilação de blocos PL/SQL: nativo e interpretado, e que o modo interpretado pode ser compilado para debug ou não!


&nbsp; &nbsp; &nbsp;O modo de compilação interpretado&nbsp;é o modo de compilação padrão e é o mais utilizado. Poucos utilizam o modo nativo, que apesar de ser mais rápido, possui algumas desvantagens, tais como: perda da portabilidade, não permite debugar o código PL/SQL e o tempo de compilação é mais demorado. As 2 primeiras desvantagens são as que mais pesam, por isso, a maioria compila seus blocos PL/SQL em modo interpretado, e muitos nem sabem da possibilidade de se efetuar a compilação em modo nativo. A compilação em modo nativo é indicada para otimizar a performance de casos muito específicos, que não são o foco deste artigo, portanto, apenas informo que explico isso no módulo extra de PL/SQL Tuning dos treinamentos PL/SQL Essentials.



&nbsp; &nbsp; &nbsp;Na compilação interpretada existem também 2 métodos de compilação: normal (ou nodebug) e debug. A compilação em modo debug deixa a execução do código mais lenta e é recomendada somente quando for realmente necessário debugar um bloco PL/SQL (ver tutorial Developing and Debugging PL/SQL using Oracle SQL Developer), caso contrário, efetue a compilação sempre no modo normal (nodebug). Para que você entenda melhor o que estou comentando e veja o quanto realmente o código compilado em modo debug pode ser mais lento, veja os testes abaixo que eu fiz, criando 2 Stored Procedures que fazem a mesma coisa (um cálculo&nbsp;hipotético&nbsp;simples) e que foram compilados, um em modo debug, e o outro em modo normal, e por fim, compare o tempo de execução deles:

&nbsp; &nbsp;





1- Criando a procedure SP_TESTA_DEBUGCOMPILE em modo debug:
ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=2;


ALTER SESSION SET PLSQL_DEBUG = TRUE;

create or replace procedure sp_testa_debugcompile is

&nbsp; v_number number := 1;

begin

&nbsp; v_number := 1 * v_number + 2 * v_number + 3 * v_number;

end;

/





2-&nbsp;Criando a procedure SP_TESTA_NODEBUGCOMPILE em modo normal:

ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=2;

ALTER SESSION SET PLSQL_DEBUG = FALSE;

create or replace &nbsp;procedure sp_testa_nodebugcompile is

&nbsp; &nbsp; &nbsp; v_number number := 1;

begin &nbsp; &nbsp;

&nbsp; v_number := 1 * v_number + 2 * v_number + 3 * v_number;

end;

/



3-&nbsp;Chamando a procedure SP_TESTA_DEBUGCOMPILE para medir o seu desempenho:

begin

&nbsp; for i in 1..9999999

&nbsp; loop

&nbsp; &nbsp; &nbsp; sp_testa_debugcompile;&nbsp;

&nbsp; end loop;

end;



Tempo médio de 3 execuções dela: ( 8,372s&nbsp;+ 8.354s&nbsp;+ 8.566s ) / 3 = &nbsp;8,43s



4-&nbsp;Chamando a procedure SP_TESTA_NODEBUGCOMPILE para medir o seu desempenho:

begin

&nbsp; for i in 1..9999999

&nbsp; loop

&nbsp; &nbsp; &nbsp; sp_testa_nodebugcompile;&nbsp;

&nbsp; end loop;

end;



Tempo médio de 3 execuções dela: ( 2,185s&nbsp;+ 2.257s&nbsp;+ 2,22s ) / 3 = &nbsp;2,22s





Obs.: As procedures foram compiladas e executadas em um Oracle Database Enterprise Edition 11.2.0.4. Se você for reproduzir os mesmos testes no Oracle 12c, leia o doc Database PL/SQL Language Reference, pois ocorreram mudanças no 12c para efetuar a compilação em modo debug.

&nbsp;&nbsp;



&nbsp;&nbsp;

CONCLUSÃO

&nbsp;&nbsp;

&nbsp; &nbsp; &nbsp;Veja que num teste simples chamando as 2 procedures&nbsp;9.999.999 vezes dentro de um loop, o tempo de execução total daquela que foi compilada em modo interpretado "normal" foi 3,80 X mais rápido do que aquela compilada em modo debug. Talvez isso lhe pareça pouco, mas saiba que em um sistema crítico que necessita de alta performance, esse pouco que na verdade foi&nbsp;380% mais rápido, pode fazer muita diferença do desempenho geral da aplicação, portanto, se você quer realmente mais performance em blocos PL/SQL armazenados, não compile-os em modo debug! Um simples detalhe (compilando em modo debug) pode deixá-lo bem mais lento, e é muito fácil cometer este engano utilizando, por exemplo, o SQL Developer (ver item "Compilar para depuração" na caixa vermelha da Imagem 01).




Imagem 01 - Compilando Procedures no SQL Developer v. 4.1.5




&nbsp; &nbsp; &nbsp;Para recompilar seus objetos PL/SQL que já foram compilados em modo debug para o modo normal (nodebug) no Oracle 11G, execute o script abaixo readequando-o de acordo com a sua necessidade:




SET SERVEROUTPUT ON

BEGIN

&nbsp; &nbsp; EXECUTE IMMEDIATE 'ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=2';

&nbsp; &nbsp; EXECUTE IMMEDIATE 'ALTER SESSION SET PLSQL_DEBUG = FALSE';



&nbsp; &nbsp; FOR LINHA IN (SELECT &nbsp;owner, name, TYPE, PLSQL_code_type, PLSQL_DEBUG

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;dba_plsql_object_settings

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; where &nbsp; PLSQL_DEBUG = 'TRUE' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )

&nbsp; &nbsp; LOOP

&nbsp; &nbsp; &nbsp; &nbsp; BEGIN

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EXECUTE IMMEDIATE 'ALTER ' || REPLACE(LINHA.TYPE, 'PACKAGE BODY', 'PACKAGE') || ' ' || LINHA.OWNER || '.' || LINHA.NAME || ' COMPILE';

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DBMS_OUTPUT.PUT_LINE('Objeto ' || linha.owner || '.' || linha.name || ' recompilado com sucesso!');

&nbsp; &nbsp; &nbsp; &nbsp; EXCEPTION

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN OTHERS THEN

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DBMS_OUTPUT.PUT_LINE('Erro ao compilar o objeto ' || linha.owner || '.' || linha.name || '!');

&nbsp; &nbsp; &nbsp; &nbsp; END; &nbsp;

&nbsp; &nbsp; END LOOP; &nbsp; &nbsp;

END;






&nbsp; &nbsp; &nbsp;
Referências:
&nbsp; &nbsp;- Oracle® DatabasePL/SQL Language Reference12c Release 1 (12.1)
&nbsp; &nbsp;