Picture of Roberto Sobrinho
Roberto Sobrinho

12/07/2024

Técnicas Tuning PL/SQL – PRAGMA INLINE na Prática


No mundo do desenvolvimento de banco de dados, a busca por performance é constante. Cada vez que um procedimento ou função é chamado em PL/SQL, existe uma pequena sobrecarga que pode se acumular, especialmente em loops. Evitar o uso de procedimentos e funções não é viável, pois precisamos manter nosso código organizado e modular. É aí que entra a PRAGMA INLINE. Esta técnica permite que o compilador substitua chamadas de subprogramas pelo código real durante a compilação, eliminando essa sobrecarga e melhorando o desempenho sem perder a modularidade do código.


O Que é PRAGMA INLINE?

A PRAGMA INLINE é uma diretiva do compilador que instrui o compilador a substituir a chamada de um subprograma pelo seu código correspondente durante a compilação. Isso elimina a sobrecarga associada às chamadas de subprogramas e pode acelerar a execução do código. Este processo é controlado pelo parâmetro PLSQL_OPTIMIZE_LEVEL e pela própria pragma INLINE.

Configurar a PRAGMA INLINE

O comportamento da PRAGMA INLINE é determinado pelo nível de otimização PLSQL_OPTIMIZE_LEVEL configurado no banco de dados:

  • Nível 0: Desativar todas as otimizações. Este nível é útil para depuração, pois mantém o código o mais próximo possível do que foi escrito, facilitando a identificação de problemas.
  • Nível 1: Ativar otimizações básicas, garantindo um bom equilíbrio entre otimização e depuração.
  • Nível 2: (Padrão) Ativar otimizações intermediárias que melhoram a performance sem comprometer significativamente a capacidade de depuração.
  • Nível 3: Ativar otimizações agressivas, podendo alterar a ordem de execução do código e inlining de subprogramas. Este nível proporciona a melhor performance, mas pode dificultar a depuração.

O parâmetro PLSQL_OPTIMIZE_LEVEL pode ser ajustado para a sessão atual usando o comando:

ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 2;

Ou configurá-lo globalmente a nível de sistema, utilizar:

ALTER SYSTEM SET PLSQL_OPTIMIZE_LEVEL = 2 SCOPE = BOTH SID='*';

Detalhes Técnicos

Pragma INLINE

A pragma INLINE pode ser usada para sugerir ao compilador que um subprograma específico deve ser inline. Isso é especialmente útil quando queremos garantir que subprogramas críticos sejam inline para otimização de desempenho. A sintaxe para usar a pragma INLINE é:

PRAGMA INLINE(nome_do_subprograma, 'YES');

Para desativar o inline:

PRAGMA INLINE(nome_do_subprograma, 'NO');

Funções Internas e Externas

Funções Internas são aquelas definidas dentro de blocos anônimos ou dentro de outros subprogramas (como procedimentos ou funções). Elas são conhecidas apenas dentro do escopo onde foram definidas e não podem ser chamadas de fora desse escopo. Como o compilador tem acesso direto ao corpo da função durante a compilação, a PRAGMA INLINE pode ser facilmente aplicada. Isso permite que o compilador substitua a chamada da função pelo próprio código da função, eliminando a sobrecarga da chamada de função.

Funções Externas são aquelas definidas fora do escopo onde são chamadas, geralmente em pacotes ou unidades de programa separadas. Elas podem ser chamadas de diferentes partes do código PL/SQL. No caso de funções externas, a PRAGMA INLINE também pode ser aplicada, mas o compilador precisa ter acesso ao corpo da função durante a compilação para poder fazer o inline. Isso significa que o código da função deve estar disponível e visível para o compilador no momento da compilação. Se a função estiver em um pacote separado que não é visível durante a compilação, o compilador não poderá aplicar o inline. No entanto, se a função externa estiver no mesmo pacote ou for compilada junto com o código que a chama, a PRAGMA INLINE pode ser utilizado.

Exemplo Prático de Desempenho

Mostrar o impacto da PRAGMA INLINE com um exemplo prático, usando uma função para calcular o delta e medindo seu desempenho em diferentes configurações de otimização.
Mediremos o tempo de execução dessa função sob diferentes configurações de otimização.

PLSQL_OPTIMIZE_LEVEL=2 e Sem PRAGMA INLINE

Executar a função sem usar a pragma INLINE, com o PLSQL_OPTIMIZE_LEVEL configurado para 2:

ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=2;

SET SERVEROUTPUT ON;
EXEC DBMS_OUTPUT.ENABLE(1000000);

DECLARE
  v_inicio  NUMBER;
  v_delta NUMBER;

  FUNCTION FNC_GUINA_CALCULAR_DELTA(a NUMBER, b NUMBER, c NUMBER) 
  RETURN NUMBER IS
    n NUMBER;
  BEGIN
    RETURN (b * b - 4 * a * c);
  END FNC_GUINA_CALCULAR_DELTA;

BEGIN
  v_inicio := DBMS_UTILITY.get_time;

  FOR i IN 1 .. 90000000 LOOP
    v_delta := FNC_GUINA_CALCULAR_DELTA(10*i, i, 10*i/5);
  END LOOP;

  DBMS_OUTPUT.put_line('Tempo OPTIMIZE_LEVEL=2 E SEM INLINE: ' || (DBMS_UTILITY.get_time - v_inicio) || ' centésimos de segundo');
END;
/

PLSQL_OPTIMIZE_LEVEL=2 e Com PRAGMA INLINE

Incluir a pragma INLINE para ativar o inline das chamadas à função dentro do loop:

ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=2;

SET SERVEROUTPUT ON;
EXEC DBMS_OUTPUT.ENABLE(1000000);

DECLARE
  v_inicio  NUMBER;
  v_delta NUMBER;

  FUNCTION FNC_GUINA_CALCULAR_DELTA(a NUMBER, b NUMBER, c NUMBER) 
  RETURN NUMBER IS
    n NUMBER;
  BEGIN
    RETURN (b * b - 4 * a * c);
  END FNC_GUINA_CALCULAR_DELTA;

BEGIN
  v_inicio := DBMS_UTILITY.get_time;

  FOR i IN 1 .. 90000000 LOOP
    PRAGMA INLINE (FNC_GUINA_CALCULAR_DELTA, 'YES');
    v_delta := FNC_GUINA_CALCULAR_DELTA(10*i, i, 10*i/5);
  END LOOP;

  DBMS_OUTPUT.put_line('Tempo OPTIMIZE_LEVEL=2 E SEM INLINE: ' || (DBMS_UTILITY.get_time - v_inicio) || ' centésimos de segundo');
END;
/

PLSQL_OPTIMIZE_LEVEL=3 e PRAGMA INLINE Implícito

Configurar o PLSQL_OPTIMIZE_LEVEL para 3 e executar o código sem a pragma INLINE, esperando que o otimizador decida fazer o inline automaticamente:

ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=3;

SET SERVEROUTPUT ON;
EXEC DBMS_OUTPUT.ENABLE(1000000);

DECLARE
  v_inicio  NUMBER;
  v_delta NUMBER;

  FUNCTION FNC_GUINA_CALCULAR_DELTA(a NUMBER, b NUMBER, c NUMBER) 
  RETURN NUMBER IS
    n NUMBER;
  BEGIN
    RETURN (b * b - 4 * a * c);
  END FNC_GUINA_CALCULAR_DELTA;

BEGIN
  v_inicio := DBMS_UTILITY.get_time;

  FOR i IN 1 .. 90000000 LOOP
    v_delta := FNC_GUINA_CALCULAR_DELTA(10*i, i, 10*i/5);
  END LOOP;

  DBMS_OUTPUT.put_line('Tempo OPTIMIZE_LEVEL=3: ' || (DBMS_UTILITY.get_time - v_inicio) || ' centésimos de segundo');
END;
/

Resultados e Análise

  • Tempo OPTIMIZE_LEVEL=2 E SEM INLINE: 2138 centésimos de segundo
  • Tempo OPTIMIZE_LEVEL=2 E COM INLINE: 1568 centésimos de segundo
  • Tempo OPTIMIZE_LEVEL=3: 1511 centésimos de segundo

Os resultados mostram que a utilização da pragma INLINE e / ou nível de OPTIMIZE_LEVEL 3 podem reduzir significativamente o tempo de execução, eliminando a sobrecarga das chamadas de subprogramas. Em cenários de execução de loops gigantescos, essas otimizações podem resultar em ganhos exponenciais de desempenho.

Candidatos para Otimização

Existem diversos tipos de código PL/SQL que podem se beneficiar de otimizações:

  • Declarações SQL dinâmicas antigas escritas com o pacote DBMS_SQL.
  • Código que processa muitas declarações SQL.
  • Funções invocadas em consultas, que podem ser executadas milhões de vezes.
  • Código que passa muito tempo processando resultados de consultas.
  • Código que realiza muitos cálculos numéricos.

Antes de começar a melhorar o código antigo, é importante medir como o sistema está funcionando agora. Faça um teste de desempenho para ver como ele está indo. Depois disso, veja os subprogramas antigos que o seu programa usa com frequência. Use ferramentas para analisar onde o tempo está sendo gasto. Muitas vezes, o otimizador PL/SQL já faz melhorias automáticas que podem aumentar o desempenho sem que você precise fazer mudanças manuais. Esses passos iniciais ajudam a encontrar partes do código que já foram melhoradas automaticamente e aquelas que realmente precisam de ajustes, economizando tempo e esforço.


A PRAGMA INLINE está disponível a partir da versão 11g do Oracle Database e é uma técnica eficaz para melhorar o desempenho do código PL/SQL, mantendo sua modularidade. No entanto, é essencial testar e avaliar o impacto do inline em cada caso, pois ele pode aumentar o tamanho do código compilado e, às vezes, não resultar em melhorias significativas. Usar a PRAGMA INLINE pode proporcionar grandes melhorias no desempenho dos aplicativos PL/SQL. Ajustar o nível de otimização e monitorar os resultados é fundamental para alcançar uma execução mais eficiente do seu código.


🚀🛠️ #20240712 #GuinaNãoTinhaDó #SeReagirBúmViraPó #GeneralDBA #MeteOLoko #FitaLoka #TrânsitoNaBelmira #AlagouDeNovoCampinhoBolaBranca #ProibidoCochilar #FugaCorreria 🛠️🚀



Compartilhe

Facebook
Twitter
LinkedIn
WhatsApp
Email
Print

Pesquisar

Roberto Sobrinho

Sou Roberto Fernandes Sobrinho, também conhecido como Sobrinho DBA , pós graduado em “Architecture and Database Administration”, entusiasta, dedicado e com 20 anos de experiência com Oracle Database e suas diversas distribuições e variações.

Oracle ACE Associate

2025

Specialist

Exadata Database Machine X9M

Professional

Oracle Database Administration

Professional

Oracle Database 19c: RAC, ASM, & Grid Infra Administrator

Professional

Oracle Autonomous Database Cloud

Professional

Oracle Cloud Database Migration and Integration

Professional

Oracle Database PL/SQL Developer

Associate

Oracle Cloud Infrastructure Architect

Associate

Oracle Cloud Infrastructure Foundations

Categorias

Categorias

Tags

Técnicas Tuning PL/SQL – PRAGMA INLINE na Prática