segunda-feira, 21 de novembro de 2011

Caso de Performance 1: Troca de contexto

Conforme comentei no post anterior, vou complementar agora com um exemplo simples a questão da degradação da performance em função das excessivas trocas de contexto. Basicamente, neste exemplo vamos comparar os efeitos de um loop que executa 1000 vezes fazendo o incremento de uma variável. Primeiro vou mostrar a forma lenta, com a atribuição utilizando um 'Select From Dual'. Depois, mostrarei o impacto de uma abordagem direta em PL/SQL:

oracle@hitomi:~$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.2.0 Beta on Mon Nov 21 22:49:21 2011

Copyright (c) 1982, 2010, Oracle. All rights reserved.


Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Beta

SQL> conn paulo/paulo
Connected.
SQL> set serveroutput on
SQL> declare
2 x number := 0;
3 t number := dbms_utility.get_time();
4 begin
5 for r in (select rownum from dual connect by level <= 1000)
6 loop
7 select x + 1 into x from dual;
8 end loop;
9 dbms_output.put_line('hsecs = ' || to_char(dbms_utility.get_time() - t ));
10 end;
11 /
hsecs = 15

PL/SQL procedure successfully completed.

SQL> 7 x := x + 1;;
SQL> /
hsecs = 1

PL/SQL procedure successfully completed.

SQL> 7 select x + 1 into x from dual;;
SQL> /
hsecs = 15

PL/SQL procedure successfully completed.

SQL>

Como vocês podem ver, apenas substituir o Select From Dual por uma atribuição direta resultou em uma melhora de nada menos que 15 vezes na velocidade do código! (Nota: 1 hsec é um centésimo de segundo)

Claro que a única coisa que executamos neste código é a própria atribuição e num código real a melhora pode não ser tão significativa, porém já testemunhei casos reais de até 30% de melhora com esta abordagem. Sua milhagem pode variar no que diz respeito aos percentuais, mas o que interessa é que evitar o select from dual quando existe alternativa direta em código PL/SQL é definitivamente uma boa prática que deve ser seguida.