Runtime Analysis (SAT / SE30)
📋 Visão Geral
SAT (ou SE30 em sistemas antigos) é a ferramenta de análise de performance em runtime. Permite medir o tempo de execução de programas e identificar gargalos de performance.
🎯 Para que Serve
- Medir tempo de execução do programa
- Identificar código lento
- Analisar queries SQL
- Ver tempo gasto por método/função
- Encontrar gargalos de performance
- Comparar antes/depois de otimizações
🔹 Iniciar Análise
Transaction Code
SAT (sistemas novos)
SE30 (sistemas antigos)
Passos Básicos
- SAT → Nova medição
- Inserir nome do programa
- Pressionar Execute
- Programa executa e é medido
- Ver resultados da análise
🔹 Tipos de Medição
1️⃣ Medição de Programa
REPORT z_programa_teste.
START-OF-SELECTION.
" Todo este código será medido
SELECT * FROM sflight INTO TABLE @DATA(lt_voos).
LOOP AT lt_voos INTO DATA(ls_voo).
" Processar
ENDLOOP.
Como:
1. SAT → Program: Z_PROGRAMA_TESTE
2. Execute
3. Ver resultados
2️⃣ Medição de Transaction
Exemplo: Medir SE16
- SAT → Transaction:
SE16 - Execute
- Executar ações na SE16
- Voltar ao SAT para ver resultados
3️⃣ Medição Manual (Código)
REPORT z_manual_measure.
DATA: lv_start TYPE timestampl,
lv_end TYPE timestampl,
lv_diff TYPE p DECIMALS 6.
" Iniciar medição
GET TIME STAMP FIELD lv_start.
" Código a medir
SELECT * FROM sflight INTO TABLE @DATA(lt_voos) UP TO 10000 ROWS.
LOOP AT lt_voos INTO DATA(ls_voo).
" Processar
ENDLOOP.
" Fim da medição
GET TIME STAMP FIELD lv_end.
" Calcular diferença
lv_diff = lv_end - lv_start.
WRITE: / |Tempo decorrido: { lv_diff } segundos|.
📊 Interpretar Resultados
Visão Geral
Total Runtime: 2.5 segundos
Database Time: 2.0 segundos (80%)
ABAP Time: 0.5 segundos (20%)
Interpretação: - Se Database > 70%: Otimizar SQL - Se ABAP > 70%: Otimizar código ABAP
Hit List (Lista de Campeões)
Mostra os métodos/funções mais lentos:
1. SELECT FROM SFLIGHT - 1.8s (72%)
2. LOOP AT lt_voos - 0.3s (12%)
3. APPEND TO lt_result - 0.2s (8%)
4. PERFORM calcular_total - 0.2s (8%)
Ação: Focar em otimizar os primeiros da lista!
Call Hierarchy
Mostra a árvore de chamadas:
Z_PROGRAMA
├─ SELECT FROM SFLIGHT (1.8s)
├─ PERFORM processar_dados (0.5s)
│ ├─ LOOP AT lt_voos (0.3s)
│ └─ APPEND (0.2s)
└─ WRITE (0.2s)
💡 Exemplos de Otimização
Exemplo 1: SELECT Lento
Antes (Lento):
" ❌ 5 segundos
SELECT * FROM sflight.
" Processar linha a linha
ENDSELECT.
Análise SAT:
SELECT FROM SFLIGHT: 5.0s (100%)
Depois (Rápido):
" ✅ 0.5 segundos
SELECT * FROM sflight INTO TABLE @DATA(lt_voos).
LOOP AT lt_voos INTO DATA(ls_voo).
" Processar
ENDLOOP.
Nova Análise:
SELECT FROM SFLIGHT: 0.5s (90%)
LOOP: 0.05s (10%)
Melhoria: 10x mais rápido!
Exemplo 2: FOR ALL ENTRIES Ineficiente
Antes:
" ❌ Lento se lt_docs estiver vazia
SELECT * FROM ekpo
INTO TABLE @DATA(lt_items)
FOR ALL ENTRIES IN @lt_docs
WHERE ebeln = @lt_docs-ebeln.
Análise: 3 segundos (tempo desperdiçado)
Depois:
" ✅ Verificar antes
IF lt_docs IS NOT INITIAL.
SELECT * FROM ekpo
INTO TABLE @DATA(lt_items)
FOR ALL ENTRIES IN @lt_docs
WHERE ebeln = @lt_docs-ebeln.
ENDIF.
Melhoria: Evita SELECT desnecessário
Exemplo 3: LOOP Lento
Antes:
" ❌ Lento: O(n²)
LOOP AT lt_vendas INTO DATA(ls_venda).
LOOP AT lt_clientes INTO DATA(ls_cliente).
IF ls_cliente-kunnr = ls_venda-kunnr.
" Processar
EXIT.
ENDIF.
ENDLOOP.
ENDLOOP.
Análise: 10 segundos para 1000 vendas
Depois:
" ✅ Rápido: O(n)
LOOP AT lt_vendas INTO DATA(ls_venda).
READ TABLE lt_clientes INTO DATA(ls_cliente)
WITH KEY kunnr = ls_venda-kunnr
BINARY SEARCH.
IF sy-subrc = 0.
" Processar
ENDIF.
ENDLOOP.
Melhoria: 10s → 0.5s (20x mais rápido!)
🛠️ Funcionalidades Avançadas
1. Comparar Medições
Cenário: Antes e depois de otimização
- SAT → Criar medição "ANTES"
- Executar programa
- Otimizar código
- SAT → Criar medição "DEPOIS"
- Comparar resultados
Resultado:
ANTES: 10.0s
DEPOIS: 1.0s
MELHORIA: 10x
2. SQL Trace
Ativar SQL Trace junto com SAT:
- SAT → Settings → SQL Trace: ON
- Executar medição
- Ver queries SQL executadas
Resultado:
SELECT * FROM SFLIGHT - Executed 1 time - 2.0s
- Records fetched: 1000
- Identical selects: 0
3. Memory Analysis
Ver consumo de memória:
- SAT → Settings → Memory Analysis: ON
- Executar
- Ver picos de memória
📈 Métricas Importantes
Database Time
Alto (>70%): - Otimizar SELECTs - Adicionar índices - Usar JOIN em vez de FOR ALL ENTRIES - Limitar quantidade de dados
Baixo (<30%): - Bom! Código ABAP está eficiente
ABAP Processing Time
Alto (>70%): - Otimizar LOOPs - Usar tabelas HASHED/SORTED - Evitar loops aninhados - Usar expressões modernas
Number of Database Accesses
Alto (>100): - Consolidar SELECTs - Usar JOIN - Buffer tables quando possível
💡 Exemplo Completo
Programa Lento
REPORT z_lento.
DATA: lt_vendas TYPE TABLE OF vbak,
lt_items TYPE TABLE OF vbap,
lt_clientes TYPE TABLE OF kna1.
START-OF-SELECTION.
" ❌ Problema 1: SELECT sem limite
SELECT * FROM vbak INTO TABLE lt_vendas.
" ❌ Problema 2: SELECT dentro de LOOP
LOOP AT lt_vendas INTO DATA(ls_venda).
SELECT * FROM vbap INTO TABLE lt_items
WHERE vbeln = ls_venda-vbeln.
" ❌ Problema 3: LOOP aninhado sem otimização
LOOP AT lt_items INTO DATA(ls_item).
SELECT SINGLE * FROM kna1 INTO DATA(ls_cliente)
WHERE kunnr = ls_venda-kunnr.
WRITE: / ls_cliente-name1, ls_item-matnr.
ENDLOOP.
ENDLOOP.
Análise SAT:
Total: 45 segundos
Database: 40s (89%)
- SELECT FROM VBAK: 5s
- SELECT FROM VBAP: 20s (1000 vezes!)
- SELECT FROM KNA1: 15s (5000 vezes!)
Programa Otimizado
REPORT z_rapido.
DATA: lt_vendas TYPE TABLE OF vbak,
lt_items TYPE TABLE OF vbap,
lt_clientes TYPE HASHED TABLE OF kna1
WITH UNIQUE KEY kunnr.
START-OF-SELECTION.
" ✅ Melhoria 1: Limitar quantidade
SELECT * FROM vbak INTO TABLE lt_vendas
UP TO 1000 ROWS.
" ✅ Melhoria 2: SELECT único com FOR ALL ENTRIES
IF lt_vendas IS NOT INITIAL.
SELECT * FROM vbap INTO TABLE lt_items
FOR ALL ENTRIES IN lt_vendas
WHERE vbeln = lt_vendas-vbeln.
" ✅ Melhoria 3: Buscar clientes de uma vez
SELECT * FROM kna1 INTO TABLE lt_clientes
FOR ALL ENTRIES IN lt_vendas
WHERE kunnr = lt_vendas-kunnr.
ENDIF.
" ✅ Melhoria 4: Ordenar para BINARY SEARCH
SORT lt_items BY vbeln.
" ✅ Melhoria 5: Usar tabela HASHED
LOOP AT lt_vendas INTO DATA(ls_venda).
LOOP AT lt_items INTO DATA(ls_item)
WHERE vbeln = ls_venda-vbeln.
" ✅ Melhoria 6: READ TABLE em HASHED
READ TABLE lt_clientes INTO DATA(ls_cliente)
WITH TABLE KEY kunnr = ls_venda-kunnr.
IF sy-subrc = 0.
WRITE: / ls_cliente-name1, ls_item-matnr.
ENDIF.
ENDLOOP.
ENDLOOP.
Nova Análise:
Total: 2 segundos
Database: 1.5s (75%)
- SELECT FROM VBAK: 0.5s
- SELECT FROM VBAP: 0.5s (1 vez!)
- SELECT FROM KNA1: 0.5s (1 vez!)
ABAP: 0.5s (25%)
Resultado: 45s → 2s = 22.5x mais rápido!
🎓 Boas Práticas
✅ Fazer
" 1. Medir antes de otimizar
" Não otimize às cegas!
" 2. Focar nos 20% que causam 80% do problema
" Hit List no SAT mostra isto
" 3. Comparar antes/depois
DATA lv_antes TYPE p DECIMALS 6.
DATA lv_depois TYPE p DECIMALS 6.
" 4. Documentar melhorias
" Comentar: "Otimizado de 10s para 1s"
❌ Evitar
" 1. Otimizar sem medir
" "Acho que este código está lento" ❌
" 2. Micro-otimizações prematuras
lv_x = lv_y + 1. " ✅ Legível
lv_x += 1. " ✅ Também OK
" Diferença é insignificante!
" 3. Ignorar resultados
" SAT diz: "SELECT lento" mas não corrige ❌
" 4. Não testar após otimização
" Otimizou mas quebrou funcionalidade ❌
🔗 Transactions Relacionadas
- SAT / SE30 - Runtime Analysis
- ST05 - SQL Trace (detalhado)
- ST12 - Performance Trace (completo)
- ST22 - Dumps (após otimização falhar)
🔗 Próximos Passos
- Performance - Técnicas de otimização
- SQL Otimizações - Otimizar queries
- FOR ALL ENTRIES - Usar corretamente
Tags: #Performance #SAT #RuntimeAnalysis #Otimização #ABAP