Translate

Mostrar mensagens com a etiqueta query. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta query. Mostrar todas as mensagens

quinta-feira, 22 de janeiro de 2026

💥 DB2 A REGRA QUE MUDA TUDO

 

Bellacosa Mainframe explorando o DB2

💥 DB2 A REGRA QUE MUDA TUDO

👉 O otimizador NÃO “ama índice”
👉 Ele escolhe o menor custo estimado

💡 Tradução Bellacosa:

Índice ruim pode ser pior que scan completo 😱


🧠 1. TABLESPACE SCAN vs INDEX SCAN

⚡ INDEX SCAN (ACCESSTYPE = 'I')

✔ Busca direta
✔ Poucas linhas retornadas
✔ Usa chave/index

👉 Ideal para:

WHERE ID = 100

🐢 TABLESPACE SCAN (ACCESSTYPE = 'R')

✔ Varre tudo
✔ Melhor quando retorna MUITAS linhas

👉 Ideal para:

SELECT * FROM CLIENTES

💣 CENÁRIO REAL 1 — “ÍNDICE IGNORADO”

🧪 Query

SELECT *
FROM CLIENTES
WHERE CIDADE = 'SAO PAULO';

👉 Você criou índice em CIDADE… mas Db2 usa SCAN 😬


🧠 Por quê?

👉 Baixa seletividade

Se:

  • 80% da tabela = “SAO PAULO”

Então:

Índice não compensa


🛠️ Solução

✔ Criar índice composto:

CREATE INDEX IDX1
ON CLIENTES (CIDADE, ID);

✔ Ou melhorar filtro


💣 CENÁRIO REAL 2 — “MATCHCOLS BAIXO”

🧪 Índice:

CREATE INDEX IDX2
ON CLIENTES (CIDADE, NOME);

🧪 Query:

SELECT * FROM CLIENTES
WHERE NOME = 'ANA';

😬 Resultado

👉 MATCHCOLS = 0


🧠 Por quê?

👉 Ordem do índice importa!


🛠️ Correção

✔ Criar índice correto:

CREATE INDEX IDX3
ON CLIENTES (NOME);

💣 CENÁRIO REAL 3 — “SELECT * MATA PERFORMANCE”

🧪 Query

SELECT * FROM CLIENTES
WHERE ID = 10;

🧠 Problema

Mesmo com índice:

👉 Pode forçar acesso à tabela (data page)


🛠️ Otimização (Index Only Access)

SELECT ID FROM CLIENTES
WHERE ID = 10;

✔ Usa só o índice
✔ Muito mais rápido


💣 CENÁRIO REAL 4 — “RUNSTATS TE TRAIU”

🧪 Situação

  • Índice existe
  • Query boa
  • Mesmo assim: SCAN 😡

🧠 Causa

👉 Estatísticas desatualizadas


🛠️ Solução

RUNSTATS TABLESPACE DB1.TS1;

💡 Sem isso:

Otimizador “chuta”


🚀 CENÁRIO REAL 5 — “RANGE SCAN”

🧪 Query

SELECT * FROM CLIENTES
WHERE ID BETWEEN 1 AND 100;

🧠 Possível acesso

✔ Index range scan
✔ Ou scan completo (depende do volume)


🧠 DECISÃO DO OTIMIZADOR

Ele avalia:

  • Cardinalidade
  • Seletividade
  • Cluster ratio
  • Número de páginas
  • Estatísticas (RUNSTATS)

💥 GOLDEN RULES (nível expert)

🥇 1. Índice ≠ sempre melhor

🥇 2. Ordem do índice é tudo

🥇 3. RUNSTATS é obrigatório

🥇 4. SELECT * é inimigo

🥇 5. WHERE define performance


🔥 CHECKLIST DE GUERRA

Antes de subir:

✔ EXPLAIN rodado
✔ ACCESSTYPE correto
✔ MATCHCOLS adequado
✔ Índice alinhado ao WHERE
✔ RUNSTATS atualizado


😎 FRASES DE ARQUITETO

  • “Isso tá com baixa seletividade”
  • “Esse índice não casa com o predicado”
  • “O access path tá custando caro”
  • “Isso aí vai virar tablespace scan em produção”

Uma revisão das regras do Db2


💣 VISÃO FINAL (MENTALIDADE)

👉 Você não escreve SQL…
👉 Você negocia com o otimizador


quarta-feira, 21 de janeiro de 2026

💥 DB2 LAB: EXPLAIN + ACCESS PATH (na prática)

 

Bellacosa Mainframe explique Explain e Access Path

💥 DB2 LAB: EXPLAIN + ACCESS PATH (na prática)

🎯 Objetivo

👉 Entender como o Db2 decide acessar os dados
👉 Identificar quando está lento
👉 Corrigir com índice + estatísticas


🧪 PARTE 1 — Criando o cenário (problema real)

🔹 Tabela sem índice

CREATE TABLE VAGNER.CLIENTES (
ID INTEGER,
NOME VARCHAR(50),
CIDADE VARCHAR(50)
);

🔹 Inserindo volume (simulação)

INSERT INTO VAGNER.CLIENTES VALUES (1,'ANA','SP');
INSERT INTO VAGNER.CLIENTES VALUES (2,'JOAO','RJ');
-- imagine milhares de registros...

🔹 Query problemática

SELECT * FROM VAGNER.CLIENTES
WHERE ID = 2;

💡 Parece simples… mas sem índice:

💥 TABLE SPACE SCAN (varre tudo)


🔍 PARTE 2 — Rodando EXPLAIN

🔹 Comando

EXPLAIN PLAN FOR
SELECT * FROM VAGNER.CLIENTES
WHERE ID = 2;

🔹 Consultando resultado

SELECT
PLANNO,
METHOD,
ACCESSTYPE,
MATCHCOLS
FROM PLAN_TABLE;

💣 Interpretação

CampoSignificado
ACCESSTYPE = 'R'Table scan 😬
ACCESSTYPE = 'I'Index scan 😎
MATCHCOLSQuantas colunas do índice usadas

⚠️ Resultado esperado (ruim)

ACCESSTYPE = R

👉 Tradução:

Db2 está varrendo a tabela inteira


🚀 PARTE 3 — Corrigindo (tuning real)

🔹 Criar índice

CREATE INDEX IDX_CLIENTES_ID
ON VAGNER.CLIENTES (ID);

🔹 Atualizar estatísticas

RUNSTATS TABLESPACE VAGNER.TSCLIENTES;

💡 Sem RUNSTATS:

O otimizador fica “cego”


🔁 PARTE 4 — Rodar EXPLAIN novamente

Mesmo comando:

EXPLAIN PLAN FOR
SELECT * FROM VAGNER.CLIENTES
WHERE ID = 2;

✅ Novo resultado

ACCESSTYPE = I
MATCHCOLS = 1

👉 Agora sim:

⚡ Usa índice
⚡ Muito mais rápido


💥 PARTE 5 — Comparação real

AntesDepois
Table scanIndex scan
Lento 🐢Rápido ⚡
Alto CPUBaixo CPU

🧠 PARTE 6 — Entendendo o Access Path

👉 O otimizador decide baseado em:

  • Estatísticas (RUNSTATS)
  • Índices disponíveis
  • Filtro (WHERE)
  • Volume de dados

💣 CASOS REAIS DE PRODUÇÃO

⚠️ 1. Índice existe, mas não usa

👉 Possível causa:

  • RUNSTATS desatualizado

⚠️ 2. MATCHCOLS = 0

👉 Índice não está sendo aproveitado


⚠️ 3. SELECT *

👉 Pode forçar acesso desnecessário


🔥 DICAS DE OURO

✔ Sempre rodar EXPLAIN antes de produção
✔ Criar índice baseado no WHERE
✔ Atualizar RUNSTATS regularmente
✔ Evitar SELECT *


🧠 MINI CHECKLIST (antes de subir código)

  • EXPLAIN OK?
  • ACCESSTYPE = I?
  • MATCHCOLS > 0?
  • RUNSTATS atualizado?

😎 FRASE DE SENIOR

“Sem EXPLAIN, você está programando no escuro.”


segunda-feira, 12 de março de 2018

☕🔥 SQL NO DB2 MAINFRAME — A LINGUAGEM QUE MOVE O DINHEIRO DO PLANETA (E QUE MUITA GENTE USA SEM ENTENDER)

 

Bellacosa Mainframe e a linguagem sql do db2

☕🔥 SQL NO DB2 MAINFRAME — A LINGUAGEM QUE MOVE O DINHEIRO DO PLANETA (E QUE MUITA GENTE USA SEM ENTENDER)

Hoje existe uma geração inteira que aprendeu SQL em:

  • MySQL

  • PostgreSQL

  • SQL Server

  • SQLite

  • cursos rápidos de Data Analytics

E aí nasce uma ilusão perigosa:

“SQL é só SELECT.”

Só que quando alguém entra no universo do DB2 Mainframe…

descobre rapidamente que SQL corporativo REAL é outra dimensão.

Porque no IBM Mainframe, SQL não é apenas consulta.

🔥 SQL no DB2 é infraestrutura crítica mundial.

É ele que movimenta:

  • bancos

  • cartões

  • seguradoras

  • bolsas de valores

  • governos

  • companhias aéreas

  • telecomunicações

E o mais impressionante:

👉 Grande parte do planeta depende diariamente de comandos SQL rodando em DB2 no z/OS.


☕ O QUE TORNA O DB2 MAINFRAME DIFERENTE?

Muita gente pensa:

“SQL é tudo igual.”

Não.

O DB2 z/OS foi construído para:

  • altíssimo volume

  • concorrência extrema

  • integridade transacional

  • recuperação sofisticada

  • segurança corporativa

  • bilhões de linhas

  • milhares de usuários simultâneos

Enquanto bancos menores focam simplicidade…

o DB2 Mainframe foi projetado para sobreviver ao caos corporativo.


☕🔥 SECTION 1 — SELECT: O COMANDO MAIS SUBESTIMADO DA HISTÓRIA

Todo mundo aprende:

SELECT * FROM CLIENTES;

E acha que domina SQL.

No Mainframe isso pode virar um desastre.


☕ O “SELECT *” É QUASE UMA HERESIA NO DB2

Em ambientes críticos:

SELECT *

pode causar:

  • I/O desnecessário

  • uso excessivo de buffer pool

  • degradação de CPU

  • aumento de GETPAGE

  • piora no access path


☕ O PROFISSIONAL MAINFRAME PENSA DIFERENTE

Ele faz:

SELECT
    NOME,
    SALDO,
    LIMITE
FROM CLIENTES
WHERE ID_CLIENTE = :WS-ID

Somente os campos necessários.


☕ Por quê?

Porque no z/OS:

🔥 performance é religião.


☕🔥 O OTIMIZADOR DO DB2 É UMA ENTIDADE QUASE “VIVA”

Pouca gente entende isso.

O DB2 Optimizer:

  • escolhe access path

  • decide índice

  • calcula custo

  • analisa estatísticas

  • estima cardinalidade

Tudo automaticamente.


☕ Exemplo clássico

Mesma query.

Dois ambientes.

Performances totalmente diferentes.

Por quê?

Porque:

  • RUNSTATS mudou

  • índices mudaram

  • volume mudou

  • clustering mudou

O Optimizer escolheu outro caminho.


☕🔥 SECTION 2 — WHERE: O LUGAR ONDE NASCEM AS GUERRAS DE PERFORMANCE

Aqui mora o verdadeiro poder do SQL.


☕ Exemplo simples

SELECT *
FROM CONTAS
WHERE CPF = '12345678900'

☕ Parece inocente…

Mas no DB2 Mainframe isso envolve:

  • matching columns

  • indexability

  • stage 1/stage 2 predicates

  • filter factor

  • synchronous I/O

  • list prefetch


☕🔥 STAGE 1 vs STAGE 2 — O TERROR DOS INICIANTES

No DB2:

Stage 1

Mais eficiente.

Executado mais próximo do Data Manager.


Stage 2

Mais custoso.

Mais CPU.

Mais processamento.


☕ Exemplo ruim

WHERE YEAR(DATA) = 2025

Pode inutilizar índice.


☕ Melhor abordagem

WHERE DATA >= '2025-01-01'
AND DATA <  '2026-01-01'

Agora o índice pode trabalhar.

🔥 Isso é mentalidade mainframe.


☕🔥 SECTION 3 — ORDER BY: O “SORT INVISÍVEL” QUE DESTRÓI BATCHES

Muita gente não percebe:

ORDER BY

quase sempre significa:

🔥 SORT.

E SORT em grandes volumes pode custar caro.


☕ O que o DB2 tenta fazer?

Evitar sort.


☕ Como?

Usando índice na ordem correta.

Exemplo:

Índice:

CPF ASC

Query:

ORDER BY CPF

O DB2 pode evitar sort completamente.


☕🔥 SECTION 4 — FUNÇÕES DE AGREGAÇÃO: O PODER ANALÍTICO CORPORATIVO

Aqui o DB2 vira máquina de inteligência.


☕ COUNT

SELECT COUNT(*)
FROM TRANSACOES

☕ Em Mainframe isso pode significar:

  • milhões

  • bilhões

  • trilhões

de registros.


☕ O detalhe assustador

Em grandes ambientes:

COUNT(*)

mal otimizado pode consumir recursos absurdos.


☕🔥 SUM e AVG NO MUNDO FINANCEIRO

SELECT SUM(VALOR)
FROM PIX

Isso movimenta literalmente bilhões de reais.


☕ Precisão no Mainframe é crítica

Erro de arredondamento?

🔥 Catástrofe financeira.


☕🔥 SECTION 5 — GROUP BY: O CÉREBRO DOS RELATÓRIOS CORPORATIVOS

O GROUP BY é onde SQL começa a parecer inteligência artificial corporativa.


☕ Exemplo

SELECT
    AGENCIA,
    SUM(SALDO)
FROM CONTAS
GROUP BY AGENCIA

☕ Isso permite:

  • analytics

  • BI

  • auditoria

  • relatórios financeiros

  • antifraude


☕ O perigo oculto

GROUP BY pode gerar:

  • grandes SORTs

  • WORKFILES gigantes

  • uso excessivo de TEMP DB


☕🔥 SECTION 6 — HAVING: O FILTRO “PÓS-INTELIGÊNCIA”

HAVING filtra após agregação.


☕ Exemplo

SELECT
    AGENCIA,
    COUNT(*)
FROM CONTAS
GROUP BY AGENCIA
HAVING COUNT(*) > 1000

☕ O detalhe técnico

HAVING normalmente custa mais que WHERE.

Porque:

  • primeiro agrega

  • depois filtra


☕🔥 SECTION 7 — JOINS: O CAMPO DE BATALHA DO DB2

Aqui mora a verdadeira engenharia SQL.


☕ Nested Loop Join

Bom para pequenos volumes.


☕ Merge Scan Join

Excelente para grandes conjuntos ordenados.


☕ Hybrid Join

Mistura estratégias.


☕ O DBA Mainframe vive disso

Analisando:

  • PLAN_TABLE

  • EXPLAIN

  • access path

  • RID list

  • prefetch


☕ Exemplo clássico

SELECT *
FROM CLIENTE C
JOIN CONTA X
ON C.ID = X.ID_CLIENTE

☕ Parece simples…

Mas por trás o DB2 pode fazer:

  • tablespace scan

  • index scan

  • sort merge

  • parallelism


☕🔥 SECTION 8 — LIMIT/FETCH FIRST: O SALVADOR DA CPU

No mundo distribuído usam:

LIMIT 10

No DB2 z/OS:

FETCH FIRST 10 ROWS ONLY

☕ Isso reduz:

  • CPU

  • I/O

  • tempo de resposta


☕ Muito usado em:

  • APIs REST

  • dashboards

  • consultas online

  • mobile


☕🔥 SECTION 9 — ALIAS: A LEITURA HUMANA DO CAOS

Grandes queries corporativas ficam monstruosas.

Alias salva vidas.


☕ Exemplo

SELECT
    C.NOME,
    X.SALDO
FROM CLIENTE C,
     CONTA X

☕ Sem alias?

Viraria insanidade visual.


☕🔥 SECTION 10 — CASE: A INTELIGÊNCIA EMBUTIDA NO SQL

CASE transforma SQL em mecanismo decisório.


☕ Exemplo

SELECT
CASE
   WHEN SALDO < 0
      THEN 'DEVEDOR'
   ELSE 'POSITIVO'
END
FROM CONTAS

☕ O Mainframe usa isso em:

  • scoring

  • antifraude

  • classificação

  • regras de negócio

  • compliance


☕🔥 O QUE OS CURSOS DE SQL NORMALMENTE NÃO ENSINAM

No DB2 Mainframe existem conceitos avançados gigantescos:

  • locking

  • isolation level

  • package

  • bind

  • commit

  • rollback

  • UR/CS/RS/RR

  • deadlock

  • claim/drain

  • RID pool

  • EDM pool

  • buffer pool

Aí o jogo muda completamente.


☕🔥 O DB2 NÃO É “SÓ UM BANCO”

Ele é:

um sistema operacional de dados corporativos.


☕🔥 A GRANDE VERDADE

O SQL que roda no notebook do estudante…

e o SQL que roda no z/OS…

podem parecer iguais.

Mas estão separados por:

  • escala

  • criticidade

  • engenharia

  • confiabilidade

  • performance

  • complexidade


☕🔥 CONCLUSÃO — SQL NO MAINFRAME NÃO É MODA. É SOBREVIVÊNCIA.

No mundo moderno:

  • apps falham

  • containers reiniciam

  • microsserviços quebram

Mas o DB2 continua lá.

Processando:

  • pagamentos

  • cartões

  • PIX

  • reservas aéreas

  • bolsas financeiras

24x7.

E talvez essa seja a maior lição do Mainframe:

🔥 “SQL não é apenas consulta.
É a linguagem silenciosa que mantém a economia mundial funcionando.”


segunda-feira, 31 de janeiro de 2011

🔥 Aprender COBOL com DB2 — o caminho do programador mainframer de verdade

 

Aprenda COBOL com DB2 ao estilo Bellacosa Mainframe

🔥 Aprender COBOL com DB2 — o caminho do programador mainframer de verdade



🧠 Introdução: por que COBOL + DB2 ainda manda no jogo

Se você quer ser programador mainframe COBOL com DB2, precisa entender uma verdade simples:

COBOL processa.
DB2 guarda.
SQL conecta o cérebro à memória do negócio.

Não estamos falando de tecnologia “antiga”.
Estamos falando da infraestrutura que processa bilhões por dia, com ACID, consistência e auditoria que muita stack moderna ainda tenta copiar.

Esse artigo é um mapa de estrada, do zero até o código profissional, misturando:

  • técnica

  • história

  • prática

  • fofoca de data center

  • e aquela sabedoria que só mainframer velho passa no café ☕


DB2 o banco de dados do Mainframe


🧱 PARTE 1 — Conhecendo o DB2 (o coração dos dados)

📜 Um pouco de história

O DB2 nasce na IBM nos anos 80, baseado no modelo relacional proposto por Edgar F. Codd.

👉 Conceito revolucionário:

  • dados em tabelas

  • relações lógicas

  • SQL como linguagem declarativa

Enquanto o mundo brigava com arquivos VSAM:

“Me diga o que você quer, não como buscar.”


🧩 Modelo Relacional (base de tudo)

  • Tabela → entidade de negócio

  • Linha (row) → registro

  • Coluna (column) → atributo

  • Primary Key → identidade

  • Foreign Key → relacionamento

💬 Bellacosa comenta:

“Se você não entende modelo relacional, não adianta saber COBOL.”


🧾 Tipos de Dados DB2 (o casamento com COBOL)

DB2COBOL
CHAR / VARCHARPIC X
INTEGERPIC S9
DECIMALPIC S9V
DATEPIC X(10)
TIMESTAMPPIC X(26)

🥚 Easter egg:
DB2 guarda DECIMAL melhor do que muito banco moderno guarda FLOAT 😏


Queries SQL no DB2 

🧑‍💻 PARTE 2 — Linguagem SQL no DB2

🗣️ SQL: a língua franca dos dados

SQL não é procedural.
SQL é declarativa.

🔹 DDL — Data Definition Language

CREATE TABLE CLIENTE ( ID_CLIENTE INTEGER NOT NULL, NOME VARCHAR(50), SALDO DECIMAL(9,2), PRIMARY KEY (ID_CLIENTE) );
  • CREATE

  • DROP

  • ALTER


🔹 DCL — Data Control Language

GRANT SELECT ON CLIENTE TO USER01;

Controle de acesso.
Segurança raiz de banco.


🔹 DML — Data Manipulation Language

INSERT INTO CLIENTE VALUES (1, 'JOÃO', 1500.00); SELECT * FROM CLIENTE; UPDATE CLIENTE SET SALDO = SALDO + 100 WHERE ID_CLIENTE = 1; DELETE FROM CLIENTE WHERE ID_CLIENTE = 1;

💬 Bellacosa:

“DELETE sem WHERE é como RM -RF /”


🔍 SELECT, JOIN e afins (onde o bicho pega)

SELECT C.NOME, P.VALOR FROM CLIENTE C JOIN PEDIDO P ON C.ID_CLIENTE = P.ID_CLIENTE;

👉 JOIN mal feito = batch lento = gente te ligando às 3 da manhã.


🛠️ SPUFI e QMF

  • SPUFI → SQL direto no TSO

  • QMF → consultas, relatórios, análise

💡 Dica Bellacosa:

“Todo mundo começa no SPUFI.
Quem fica bom, aprende QMF.”



🧩 PARTE 3 — COBOL com DB2 (onde nasce o profissional)

🏛️ História rápida do COBOL

  • Criado em 1959

  • Foco: negócio

  • Legibilidade

  • Estabilidade

👉 Não é bonito.
👉 É confiável.


🧠 Estrutura de um programa COBOL

  • IDENTIFICATION DIVISION

  • ENVIRONMENT DIVISION

  • DATA DIVISION

  • PROCEDURE DIVISION

📌 Árvore programática é fundamental para não virar macarrão lógico.


🔗 Host Variables (a ponte COBOL ↔ DB2)

EXEC SQL SELECT SALDO INTO :WS-SALDO FROM CLIENTE WHERE ID_CLIENTE = :WS-ID END-EXEC.
  • Sempre com :

  • Tipagem correta

  • Conversão consciente


📊 SQLCA — seu melhor amigo

IF SQLCODE = 0 CONTINUE ELSE DISPLAY 'ERRO DB2 ' SQLCODE END-IF
SQLCODESignificado
0OK
+100NOT FOUND
< 0ERRO

💬 Bellacosa:

“Quem ignora SQLCODE vira operador sem saber.”


📚 DCLGEN — o BOOK sagrado

  • Gera layout da tabela

  • Gera host variables

  • Evita erro humano

//STEP01 EXEC PGM=DSNTEP2

👉 Nunca escreva layout DB2 na mão. Nunca.


Consulta pagina via cursor no DB2

🌀 PARTE 4 — Cursores (nível profissional)

🔄 Cursor para leitura

EXEC SQL DECLARE C1 CURSOR FOR SELECT ID_CLIENTE, NOME FROM CLIENTE END-EXEC.
EXEC SQL FETCH C1 INTO :WS-ID, :WS-NOME END-EXEC.

📌 Sempre:

  • OPEN

  • FETCH

  • CLOSE


✍️ Inserindo, alterando e excluindo via COBOL

  • INSERT → novo registro

  • UPDATE → alteração controlada

  • DELETE → cuidado máximo

💡 Boa prática:

“Nunca DELETE direto sem histórico.”


🧠 PARTE 5 — Boas práticas Bellacosa Mainframe

✔ Use DCLGEN
✔ Sempre trate SQLCODE
✔ Evite SELECT *
✔ Documente regra de negócio
✔ Separe lógica de acesso a dados
✔ Teste com volume real
✔ Pense em performance desde o SELECT

🥚 Easter egg clássico:

“O batch estava lento porque alguém esqueceu o índice.”


🧪 Exercícios de fixação (mentalidade correta)

  1. Criar tabela DB2

  2. Gerar DCLGEN

  3. Programa COBOL com:

    • INSERT

    • SELECT

    • UPDATE

    • DELETE

  4. Programa com CURSOR

  5. Programa com JOIN

  6. Analisar SQLCODE

  7. Ajustar performance

👉 Isso forma programador, não copiador de código.


🧠 Comentário final Bellacosa

Aprender COBOL com DB2 não é aprender uma linguagem.
É aprender:

  • como dados movem o mundo

  • como sistemas críticos pensam

  • como escrever código que não pode falhar

🔥 COBOL + DB2 não é passado.
É o núcleo silencioso do presente.

Enquanto modas passam,
o batch fecha o dia.

 

domingo, 4 de outubro de 2009

🔷 INNER JOIN no IBM DB2 Mainframe – A Arte de Relacionar Tabelas

 

Bellacosa Mainframe apresenta IBM Mainframe DB2 Inner Join

🔷 INNER JOIN no IBM DB2 Mainframe – A Arte de Relacionar Tabelas

Se você trabalha com IBM Mainframe, provavelmente já precisou combinar dados de diferentes tabelas. E para isso existe o INNER JOIN, que é o clássico entre os joins em SQL.

Mas antes de entrar nos detalhes, vamos à história…


🕰️ História e Origem

O conceito de INNER JOIN vem diretamente do Modelo Relacional de Codd (1970), criado dentro da IBM.

  • Edgar F. Codd, um cientista da IBM, imaginou que dados deveriam ser armazenados em tabelas relacionais e manipulados por álgebra relacional.

  • Ele não inventou “INNER JOIN” como conhecemos hoje, mas a ideia de combinar tabelas via chaves comuns nasceu com ele.

  • SQL evoluiu nos anos 80 para suportar explicitamente joins:

    • Sintaxe implícita: FROM A, B WHERE A.key = B.key

    • Sintaxe explícita: FROM A INNER JOIN B ON A.key = B.key

No DB2 para Mainframe, o INNER JOIN é altamente otimizado para lidar com milhões de linhas em transações batch ou OLTP, mantendo a performance crítica.


⚙️ O que é INNER JOIN?

INNER JOIN é a operação que retorna somente as linhas onde existe correspondência em ambas as tabelas, baseado em uma chave comum.

🔹 Sintaxe padrão DB2

-- Explicit INNER JOIN (recomendado) SELECT E.EmployeeID, E.LastName, O.OrderID FROM Employees E INNER JOIN Orders O ON E.EmployeeID = O.EmployeeID;
-- Implicit INNER JOIN (estilo antigo) SELECT E.EmployeeID, E.LastName, O.OrderID FROM Employees E, Orders O WHERE E.EmployeeID = O.EmployeeID;

🔹 Observações

  • Chave comum: não precisa ter o mesmo nome, apenas valores compatíveis.

  • Sem correspondência → linha é descartada.

  • Pode usar múltiplas tabelas → INNER JOIN é associativo.


💡 Dicas Bellacosa para Mainframe

  1. Prefira joins explícitos (INNER JOIN ON) em DB2 → facilita leitura e manutenção.

  2. Sempre qualifique colunas se houver nomes repetidos → evita ambiguidade (E.EmployeeID, O.EmployeeID).

  3. Use aliases curtos → economiza digitação e deixa o código limpo.

  4. Evite cartesian products sem intenção → FROM A, B sem WHERE é um Product, que explode linhas.

  5. Verifique estatísticas de tabela → DB2 otimiza join usando índices.


🔍 Curiosidades & Easter Eggs

  • No DB2, todas as joins são INNER por padrão se você não usar OUTER.

  • Internamente, o otimizador transforma INNER JOIN em operações de álgebra relacional: Product + Selection.

  • Usar JOIN explícito ajuda o Explain Plan a gerar caminhos de acesso mais eficientes.

  • Combinar índices corretos + INNER JOIN = batch mais rápido, menos I/O.


🧪 Exemplo prático

Imagine que temos duas tabelas no z/OS DB2:

EMPLOYEES

EmployeeIDLastNameDeptID
101Smith10
102Jones20

DEPARTMENTS

DeptIDDeptName
10Accounting
20HR
30IT

Query: INNER JOIN

SELECT E.LastName, D.DeptName FROM Employees E INNER JOIN Departments D ON E.DeptID = D.DeptID;

Resultado:

LastNameDeptName
SmithAccounting
JonesHR

Observe: DeptID = 30 não aparece porque não há funcionário correspondente.


📈 Uso e Razão de Uso

  • Combinar tabelas relacionadas → RELACIONAL puro

  • Resumir informações em relatórios ou dashboards OLAP

  • Criar answer sets consistentes para análises

  • Fundamental para consultas em ERP, finanças e logística

No mainframe, INNER JOIN é usado em:

  • Batch → processa milhões de registros rapidamente

  • Online Transaction Processing (OLTP) → respostas rápidas e consistentes


⚡ Impacto na Performance e Otimização

  1. Indexes importam muito:

    • JOIN em colunas indexadas = leitura rápida, menos I/O

    • Sem índice → DB2 faz table scan → lento em tabelas grandes

  2. Estatísticas DB2:

    • RUNSTATS ajuda o otimizador a escolher o caminho ideal

  3. Número de tabelas no JOIN:

    • Mais joins = mais complexidade e consumo de CPU

    • Prefira joins em cascata controlados, evite joins desnecessários

  4. Filtros antes do JOIN:

    • Use WHERE/qualificação para reduzir linhas antes do INNER JOIN

    • Isso diminui o volume de dados processados e acelera o batch


🔑 Comentários finais Bellacosa

  • INNER JOIN é a base do SQL relacional, especialmente no DB2 do mainframe.

  • Sintaxe explícita + colunas qualificadas + índices corretos = performance top de linha.

  • Mesmo em 2026, ele é indispensável em sistemas críticos da IBM.

  • Dica bônus: use EXPLAIN PLAN para ver como DB2 executa seus INNER JOINs.

💡 Easter Egg:

Por baixo do capô, o DB2 transforma cada INNER JOIN em Product + Selection + Projection na álgebra relacional — a magia acontece silenciosa enquanto você apenas digita INNER JOIN.