Banco de DadosPerformance Oracle Oracle para Desenvolvedores Oracle Tuning.Configuração de memória Oracle (SGA/PGA)
Performance Oracle para devs: 5 erros fatais (e como corrgi-los)

Rocketseat

Navegação Rápida:
Você já viveu aquele pesadelo? Sua aplicação estava funcionando perfeitamente em desenvolvimento, testes unitários 100% cobertos, tudo lindo. Mas, quando chegou em produção, virou uma lesma cansada. O cliente liga, o suporte entra em pânico e a culpa, invariavelmente, cai onde? No banco de dados.
A verdade dói, mas precisa ser dita: estatisticamente, a maior parte dos problemas de performance em aplicações web têm origem no banco de dados. E quando falamos de ambientes robustos que utilizam Oracle, pequenos deslizes podem ter consequências catastróficas.

Mas calma, não precisa entrar em desespero.
Vamos começar analisando aquela consulta que parece inofensiva, mas que pode ser uma assassina silenciosa da sua performance:
-- Parece inofensivo, mas pode ser um assassino silencioso SELECT * FROM users WHERE UPPER(email) = 'DIEGO@ROCKETSEAT.TEAM';
Parece familiar? Então bora codar! 🚀
Erro #1 - O massacre das consultas SQL ineficientes
Vamos começar fazendo um exercício de imaginar… é sexta-feira, 17h. Você acabou de fazer o deploy da nova funcionalidade de relatório de vendas. Em minutos, o time comercial reclama que o sistema está travado. Você investiga e descobre uma única consulta que está levando 2 minutos para retornar os dados. Sentiu o frio na barriga?

Consultas SQL mal escritas são, de longe, a causa número um de problemas de performance no Oracle database. Elas consomem CPU, travam recursos e destroem a experiência do usuário.
Como identificar (antes que seus usuários reclamem)?
A chave para a otimização de SQL no Oracle é a visibilidade. Você não pode consertar o que não vê.
- EXPLAIN PLAN: essa é sua bola de cristal. O
EXPLAIN PLAN
mostra exatamente como o Oracle pretende executar sua consulta. Ele revela se o banco vai usar um índice, se vai fazer um full table scan (ler a tabela inteira) e qual o custo estimado da operação.
- SQL Developer: use o atalho para visualizar o plano de execução diretamente na sua IDE.
- Sinais de alerta: consultas que demoram mais de 5 segundos em um ambiente OLTP (transacional), picos inexplicáveis de CPU no servidor do banco e, claro, usuários irritados.
A anatomia de uma consulta assassina
Vamos usar um contexto de e-commerce. Você precisa buscar produtos pelo nome. Uma abordagem comum, mas problemática, seria:
-- ANTES: consulta que mata performance SELECT * FROM products WHERE UPPER(name) LIKE '%SMARTPHONE%';
Por que isso é ruim?
SELECT *
: você raramente precisa de todas as colunas. Trafegar dados desnecessários sobrecarrega a rede e a memória.
UPPER(name)
: aplicar uma função na coluna da cláusulaWHERE
geralmente impede o Oracle de usar um índice naquela coluna.
LIKE '%...'
: o curinga no início da busca força o Oracle a varrer a tabela inteira, pois ele não sabe por onde começar a procurar.
Agora, veja a versão otimizada:
-- DEPOIS: otimizada e feliz SELECT id, name, price FROM products WHERE name LIKE 'smartphone%' AND status = 'active';
Nesta versão, selecionamos apenas as colunas que precisamos, removemos a função
UPPER
(assumindo que tratamos o case sensitivity na aplicação ou com um índice funcional) e removemos o curinga inicial, permitindo o uso de um índice padrão.Soluções que realmente funcionam
- Reescreva suas consultas: Foque em simplicidade. Evite subqueries complexas quando um
JOIN
resolve.
- Use o EXPLAIN PLAN religiosamente: analise o "custo" (cost) da consulta. Se o custo for alto, investigue as operações que aparecem em vermelho ou que indicam full table scan.
- Crie índices estratégicos: falaremos mais sobre isso no erro #3, mas índices são vitais para evitar a leitura completa das tabelas.
Dica pro: se você encontrar consultas SQL lentas recorrentes, use o SQL Tuning Advisor (disponível em algumas versões do Oracle) para receber recomendações automáticas de otimização.
Erro #2 - configuração de memória que faz Oracle chorar
Pense no Oracle como um restaurante movimentado. A SGA (System Global Area) é a cozinha principal, onde os pratos (dados) são preparados e compartilhados. A PGA (Program Global Area) é a estação de trabalho individual de cada garçom (processo do servidor), usada para organizar pedidos e fazer tarefas específicas.

Se a cozinha for pequena demais, os cozinheiros trombam uns nos outros. Se a estação do garçom for minúscula, ele não consegue organizar os pedidos direito.
O resultado? Caos e lentidão.
A configuração inadequada de memória é um erro clássico que afeta diretamente a performance do banco de dados.
Os sinais de que sua memória está pedindo socorro
O Oracle avisa quando está sem memória. Você provavelmente verá estes erros:
- ORA-04031: "out of memory in shared pool". Significa que a SGA (a cozinha) está lotada ou fragmentada. O Oracle não consegue encontrar espaço contínuo para armazenar novas informações, como planos de execução de SQL.
- ORA-04030: "out of process memory". Significa que a PGA (a estação do garçom) esgotou. Isso geralmente acontece durante operações pesadas de ordenação ou hash joins.
Você pode verificar o uso atual com consultas simples:
-- Verificar memória livre na SGA SELECT * FROM v$sgastat WHERE name LIKE '%free memory%'; -- Verificar alocação total de PGA SELECT * FROM v$pgastat WHERE name = 'total PGA allocated';
Configuração que realmente funciona
Relaxa, não é tão complexo quanto parece. Desde o Oracle 11g, temos o Automatic Memory Management (AMM) ou o Automatic Shared Memory Management (ASMM), que facilitam muito a vida.
Em vez de microgerenciar cada componente da memória (buffer cache, shared pool, large pool), você define alvos gerais e deixa o Oracle ajustar os detalhes.
Para um projeto médio, uma configuração inicial poderia ser:
-- Configuração para projeto médio (exemplo prático) ALTER SYSTEM SET SGA_TARGET=4G SCOPE=SPFILE; ALTER SYSTEM SET PGA_AGGREGATE_TARGET=1G SCOPE=SPFILE;
SGA_TARGET
: o alvo para a memória compartilhada.
PGA_AGGREGATE_TARGET
: o alvo para a memória agregada dos processos.
SCOPE=SPFILE
: significa que a mudança será salva no arquivo de parâmetros do servidor e só terá efeito após a reinicialização da instância.
Ajustar esses valores com base na carga de trabalho real é crucial para um Oracle tuning para iniciantes bem-sucedido.
Erro #3 - A tragédia dos índices mal planejados
Tem uma história clássica no mundo dos DBAs sobre um desenvolvedor júnior que, ao tentar resolver um problema de performance, criou 47 índices diferentes na mesma tabela de pedidos. Ele achou que quanto mais índices, mais rápido ficaria.

O resultado? As consultas de leitura melhoraram marginalmente, mas as operações de
INSERT
e UPDATE
ficaram insuportavelmente lentas.Esse é o paradoxo dos índices de performance no Oracle.
Quando menos é mais (e quando mais é demais)
- Poucos índices: Forçam o Oracle a realizar full table scans para encontrar os dados, o que é lento em tabelas grandes.
- Muitos índices: Cada vez que você insere, atualiza ou deleta um registro, o Oracle precisa atualizar todos os índices associados àquela tabela. Isso gera overhead de manutenção e consome espaço em disco.
O segredo está no equilíbrio e na estratégia.
Criando índices inteligentes
Não crie índices aleatoriamente. Crie índices que suportem suas consultas mais frequentes e críticas. Siga estas regras práticas:
- Chaves primárias e estrangeiras: quase sempre devem ser indexadas (o Oracle faz isso automaticamente para chaves primárias).
- Cláusulas WHERE: colunas frequentemente usadas para filtrar dados (como
email
,status
,created_at
) são ótimas candidatas.
- Cláusulas JOIN: as colunas que conectam tabelas são cruciais para joins rápidos.
- Cláusulas ORDER BY: se você frequentemente ordena por uma coluna específica, indexá-la pode evitar operações de ordenação custosas na memória.
-- Índice estratégico para login rápido CREATE INDEX idx_user_email ON users(email); -- Índice composto para relatórios de pedidos por usuário e data CREATE INDEX idx_order_user_date ON orders(user_id, created_at);
O poder dos índices compostos
O segundo exemplo acima é um índice composto. Ele cobre consultas que filtram por
user_id
E created_at
. O Oracle pode usar esse índice de forma muito mais rápida do que usar dois índices separados ou fazer um scan completo.Dica Pro: a ordem das colunas no índice composto importa! Coloque a coluna com maior seletividade (a que filtra mais registros) primeiro.
Erro #4 - Connection pool que mais atrapalha que ajuda!
Se você é um desenvolvedor full-stack, trabalhando com Node.js, Java ou Python, você sabe que sua aplicação não fala diretamente com o Oracle. Ela usa um connection pool.

O connection pool é como uma fila de táxis prontos para levar suas requisições ao banco de dados. Em vez de gastar tempo precioso abrindo e fechando uma nova conexão TCP/IP para cada consulta (o que é lento!), sua aplicação reutiliza uma conexão existente do pool.
Quando mal configurado, esse sistema que deveria ajudar se torna o vilão.
Por que sua aplicação trava nos horários de pico
O problema mais comum é o connection storm (tempestade de conexões).
Imagine que sua aplicação tem um
poolMin
muito baixo (poucos táxis na fila) e um poolMax
muito alto. Quando o tráfego aumenta repentinamente, centenas de requisições tentam abrir novas conexões simultaneamente. Isso sobrecarrega o servidor Oracle, que não consegue atender a todos, gerando timeouts e erros como o ORA-00018: maximum number of sessions exceeded
.Configuração correta de connection pool
A configuração ideal varia, mas a regra de ouro moderna é manter o pool relativamente estático. Defina
poolMin
e poolMax
com valores próximos.Vamos ver um exemplo hipotético de configuração otimizada usando o driver
oracledb
no Node.js:// Configuração otimizada para aplicação web Node.js const oracledb = require('oracledb'); async function startApp() { try { await oracledb.createPool({ user: 'rocketseat_user', password: 'senha_segura_do_diego', connectionString: 'localhost/xepdb1', // Configurações chave para performance: poolMin: 20, // Manter conexões prontas poolMax: 25, // Evitar crescimento explosivo poolIncrement: 1 // Crescer lentamente se necessário }); // Iniciar servidor HTTP... } catch (err) { console.error('Falha ao iniciar connection pool', err); } }
poolMin
e poolMax
próximos (20 e 25), garantimos que as conexões estejam prontas para uso imediato, sem causar tempestades de conexão durante picos de acesso. Esse é um passo fundamental para garantir a performance Oracle database em aplicações web.Erro #5 - Parsing que devora CPU
Esse é o vampiro invisível da performance. Você não o vê facilmente nos relatórios de consultas lentas, mas ele está lá, sugando seus recursos de CPU silenciosamente.

Vamos usar uma analogia. Imagine que você pede a um tradutor para traduzir uma frase do português para o inglês. O tradutor analisa a frase, entende a gramática, escolhe as melhores palavras e entrega a tradução. Isso é o parsing.
Agora, imagine que você peça para traduzir a mesma frase, mudando apenas uma palavra, milhões de vezes. Se o tradutor tiver que reanalisar a gramática inteira toda vez, ele vai gastar uma energia enorme.
É exatamente isso que acontece quando o Oracle faz hard parsing excessivo.
O vampiro invisível da performance
Toda consulta SQL passa por três fases:
- Parse: Oracle verifica a sintaxe, as permissões e decide o melhor plano de execução.
- Execute: Oracle executa o plano.
- Fetch: Oracle retorna os dados para a aplicação.
O hard parsing é a parte mais custosa da fase 1. O ideal é que o Oracle faça o parse da consulta uma vez e reutilize o plano de execução (isso é chamado de soft parsing).
Você pode identificar o parsing excessivo verificando a parse ratio (razão de parsing) nas estatísticas do sistema. Se a taxa de hard parsing for alta em relação ao total de parses, você tem um problema.
Bind variables: sua arma secreta
A causa mais comum de hard parsing excessivo é o uso de valores literais nas consultas SQL em vez de bind variables (variáveis de ligação).
Veja o problema:
-- PROBLEMA: parsing desnecessário SELECT * FROM users WHERE id = 12345; SELECT * FROM users WHERE id = 12346; SELECT * FROM users WHERE id = 12347;
Para o Oracle, essas são três consultas completamente diferentes. Ele precisa fazer o hard parse de cada uma delas, mesmo que o plano de execução seja idêntico.
Agora, segura essa solução:
-- SOLUÇÃO: bind variables SELECT * FROM users WHERE id = :user_id;
Neste caso, a consulta SQL é exatamente a mesma. A aplicação apenas "liga" (binds) valores diferentes à variável
:user_id
. O Oracle faz o hard parse apenas na primeira vez e reutiliza o plano para todas as execuções subsequentes.A diferença na performance e no uso de CPU é brutal. Se você quer garantir a melhor performance no Oracle Database, use bind variables consistentemente. A maioria dos frameworks modernos e ORMs fazem isso automaticamente, mas é vital entender o que está acontecendo por baixo dos panos.
Próximos passos na sua evolução
WoW! Acabamos de enfrentar os 5 maiores vilões da performance em Oracle. Pense em quanto conhecimento você absorveu nos últimos minutos:
- Você aprendeu a diagnosticar consultas assassinas com
EXPLAIN PLAN
.
- Você entendeu como configurar a memória (SGA/PGA) sem medo.
- Você dominou a arte de criar índices estratégicos.
- Você viu como configurar um connection pool otimizado em Node.js.
- E descobriu o poder das bind variables para combater o parsing excessivo.
Agora você tem as ferramentas não apenas para consertar problemas, mas para fazer suas aplicações voarem em produção. Você está se tornando o tipo de desenvolvedor que as empresas buscam: alguém que entende a stack completa e sabe como a performance do banco de dados impacta a experiência do usuário final.
Se você aprendeu algo com esse material, compartilhe com alguém especial (se essa pessoa chegar até aqui saberá que você é importante para ela), abra um debate em nossa comunidade! Networking faz parte de nossa jornada como dev e quem é visto, é lembrado!
Artigos_
Explore conteúdos relacionados
Descubra mais artigos que complementam seu aprendizado e expandem seu conhecimento.