⚡ Performance e Boas Práticas
Guia completo para escrever código ABAP eficiente e otimizado.
📖 O que vais aprender
- Identificar e eliminar gargalos de performance
- Otimizar consultas SQL (SELECTs)
- Usar
FOR ALL ENTRIEScorretamente - Trabalhar eficientemente com tabelas internas
- Evitar armadilhas comuns (SELECT em LOOP, etc.)
- Entender e usar índices de base de dados
- Analisar performance com SAT (Runtime Analysis)
- Configurar e usar buffering de tabelas
- Escolher tipos corretos de tabelas internas
🎯 Regras de Ouro
✅ Fazer
- Minimizar acessos à BD: Agregar dados numa única query
- Usar campos indexados: WHERE com campos que têm índices
- Limitar resultados:
UP TO n ROWSquando possível - Especificar campos: Evitar
SELECT * - Usar
FOR ALL ENTRIES: Para substituir SELECTs em LOOP - Escolher tipo correto: STANDARD vs SORTED vs HASHED
❌ Evitar
- SELECT dentro de LOOP: Causa múltiplos acessos à BD ⚠️
- FOR ALL ENTRIES sem validação: Pode retornar tudo! 😱
- APPEND em LOOPs grandes: Usar
VALUE #()ouINSERT LINES OF - NESTED LOOPs: Considerar tabelas HASHED
- Modificar tabela durante LOOP: Comportamento inesperado
- SELECT *: Desperdício de recursos
🔑 Tópicos Principais
1️⃣ FOR ALL ENTRIES
Técnica essencial para evitar SELECT em LOOP e melhorar drasticamente a performance.
Exemplo rápido:
" ❌ ERRADO: 1000 queries
LOOP AT lt_orders INTO DATA(ls_order).
SELECT * FROM vbap WHERE vbeln = ls_order-vbeln...
ENDLOOP.
" ✅ CORRETO: 2 queries
IF lt_orders IS NOT INITIAL.
SELECT * FROM vbap
FOR ALL ENTRIES IN @lt_orders
WHERE vbeln = @lt_orders-vbeln...
ENDIF.
Ler mais sobre FOR ALL ENTRIES »
2️⃣ Índices de Base de Dados
Como usar índices para acelerar queries SQL até 1000x.
Pontos-chave: - Usar campos indexados no WHERE - Verificar índices existentes (SE11) - Criar índices secundários quando necessário - Medir impacto com ST05
3️⃣ Runtime Analysis (SAT)
Ferramenta para analisar performance em detalhe e identificar hotspots.
O que mede: - Tempo de execução por método - Número de queries à BD - Tempo SQL vs processamento ABAP - Consumo de memória
4️⃣ Table Buffering
Usar cache em memória para dados que não mudam frequentemente.
Tipos de buffering: - Full buffering (tabelas pequenas) - Generic buffering (por grupos) - Single record buffering (por chave)
Ganho: Até 100x mais rápido para dados bufferizados!
5️⃣ Tabelas Internas Eficientes
Escolher o tipo correto de tabela interna pode melhorar performance em 100x.
Comparação: | Tipo | READ (100k registos) | Quando Usar | |------|---------------------|-------------| | STANDARD | 50ms | LOOPs sequenciais | | SORTED | 0.5ms | Dados ordenados, READs moderados | | HASHED | 0.05ms | Muitos READs por chave |
Ler mais sobre Tabelas Internas »
6️⃣ Armadilhas Comuns
Os 10 erros mais comuns que destroem performance.
Top 3: 1. ❌ SELECT em LOOP 2. ❌ SELECT * (todos os campos) 3. ❌ FOR ALL ENTRIES sem validação
📊 Comparação: Antes e Depois da Otimização
Cenário Real: Relatório de Vendas
" ❌ ANTES: 15 minutos
LOOP AT lt_orders INTO DATA(ls_order). " 10.000 orders
SELECT * FROM vbap WHERE vbeln = ls_order-vbeln... " 10.000 SELECTs
LOOP AT lt_items INTO DATA(ls_item).
SELECT SINGLE * FROM mara WHERE matnr = ls_item-matnr... " 50.000 SELECTs
ENDLOOP.
ENDLOOP.
" ✅ DEPOIS: 30 segundos
SELECT * FROM vbak INTO TABLE @DATA(lt_orders)...
IF lt_orders IS NOT INITIAL.
SELECT * FROM vbap FOR ALL ENTRIES IN @lt_orders... " 1 SELECT
ENDIF.
" Criar HASHED table para materiais
DATA lt_materials TYPE HASHED TABLE OF mara WITH UNIQUE KEY matnr.
SELECT * FROM mara INTO TABLE @lt_materials FOR ALL ENTRIES...
" Usar lookups rápidos
LOOP AT lt_items INTO DATA(ls_item).
READ TABLE lt_materials WITH TABLE KEY matnr = ls_item-matnr...
ENDLOOP.
" Resultado: 30x mais rápido! 🚀
🧪 Ferramentas de Análise
Transações Essenciais
| Transação | Propósito | Quando Usar |
|---|---|---|
| SAT | Runtime Analysis | Medir tempo de execução detalhado |
| ST05 | SQL Trace | Ver queries SQL executadas |
| ST02 | Buffer Statistics | Monitorizar buffers |
| ST10 | Table Call Stats | Ver acessos a tabelas |
| ST22 | ABAP Dumps | Analisar erros runtime |
| SE11 | Data Dictionary | Ver índices de tabelas |
- Monitorizar todas as operações SQL
- Identificar SELECTs lentos
- Ver planos de execução
📚 Exercícios Práticos
Temos 10 exercícios progressivos em ex01.md a ex10.md:
- ex01: Otimizar SELECT dentro de LOOP
- ex02: Usar FOR ALL ENTRIES corretamente
- ex03: Trabalhar com tabelas HASHED
- ex04: Evitar NESTED LOOPs
- ex05: Buffering de tabelas
- ex06-ex10: Casos práticos de otimização
💡 Exemplo Completo: Antes e Depois
🐌 Antes (Lento)
REPORT z_performance_bad.
DATA: lt_orders TYPE TABLE OF vbak,
lt_items TYPE TABLE OF vbap.
SELECT * FROM vbak INTO TABLE lt_orders UP TO 1000 ROWS.
LOOP AT lt_orders INTO DATA(ls_order).
" ❌ SELECT dentro de LOOP - 1000 queries!
SELECT * FROM vbap
INTO TABLE @DATA(lt_temp)
WHERE vbeln = @ls_order-vbeln.
APPEND LINES OF lt_temp TO lt_items.
ENDLOOP.
Performance: ~5-10 segundos para 1000 encomendas
🚀 Depois (Rápido)
REPORT z_performance_good.
DATA: lt_orders TYPE TABLE OF vbak,
lt_items TYPE TABLE OF vbap.
SELECT * FROM vbak INTO TABLE lt_orders UP TO 1000 ROWS.
" ✅ Uma única query com FOR ALL ENTRIES
IF lt_orders IS NOT INITIAL.
SELECT * FROM vbap
INTO TABLE lt_items
FOR ALL ENTRIES IN @lt_orders
WHERE vbeln = @lt_orders-vbeln.
ENDIF.
Performance: ~0.5 segundos para 1000 encomendas
Melhoria: 10-20x mais rápido! 🎯
🔍 Tabelas Internas: Standard vs. Sorted vs. Hashed
| Tipo | Acesso | Uso ideal |
|---|---|---|
STANDARD TABLE |
Sequencial (lento) | Pequenas tabelas, sem buscas |
SORTED TABLE |
Binário (médio) | Acesso ordenado, buscas médias |
HASHED TABLE |
Hash (rápido) | Buscas frequentes com chave |
Exemplo com HASHED:
DATA lt_materials TYPE HASHED TABLE OF mara
WITH UNIQUE KEY matnr.
READ TABLE lt_materials WITH KEY matnr = 'MAT001'
INTO DATA(ls_mat).
" O(1) - acesso instantâneo!
🚀 Próximos Passos
- Comece por FOR ALL ENTRIES para otimizar joins
- Aprenda sobre Índices para queries mais rápidas
- Use SAT para analisar seus programas
- Implemente Buffering quando apropriado
- Otimize Tabelas Internas para melhor performance
- Evite Armadilhas Comuns de performance