Muitas e muitas vezes recebi reclamação dos meus amigos desenvolvedores sobre SQL lento.
Aí quando você pede o SQL pra dar uma olhada e faz um "simples " explain plan,que é simples mas com muitas informações realmente importantes para quem escreve SQL,você encontra um MERGE JOIN CARTESIAN ou coisa do tipo.
Minha experiência.Dificilmente precisei fazer um Cartesian Join na minha vida e mais dificil ainda encontrei alguem que criou o SQL me dizer o motivo "daquilo" ou de aquilo está acontecendo.Na maioria das vezes é falta de condição/predicados de join entre as tabelas.E com uma simples conferencia você acha o erro.Pode existir outras causas remotas,mas em 90 e tantos % das vezes é SQL mal escrito.
Como esta semana recebi mais uma vez um caso destes ,resolvi postar o ocorrido e alertar para quem não conhece o principal moitvo do fato ocorrer!
A SQL é usada para manipulação de dados em um banco de dados relacional,sempre tenha definido o que você precisa trazer bem como as condições que você deve "setar" no código para trazer somente o que você realmente precisa.E sempre veja o plano de execução para ver se tem como melhorar!
Escreva o SQL fazendo os ajustes necessários,no final o resultado é bem mais satisfatório!
Showing posts with label outer join.left join. Show all posts
Showing posts with label outer join.left join. Show all posts
Thursday, May 13, 2010
Wednesday, February 24, 2010
Oracle SQL - Usando LEFT and RIGHT JOIN
Olá,
Hoje o assunto é OUTER JOIN.
Essa dica de post eu peguei com o meu amigo Eduardo do blog bieduardo.blogspot.com/ .
Normalmente muitos profissionais caem nesta dúvida cruel.
Como fazer corretamente um OUTER JOIN?
Pirmeiro vamos relembrar o que é um OUTER JOIN.
"Um OUTER JOIN é um SIMPLE JOIN ou INNER JOIN com uma "opção extendida " de trazer também os dados que não satisfazem a condição de JOIN.
No Oracle para usar LEFT ou RIGHT OUTER JOIN em seu SQL você pode usar o caracter "+" entre parênteses para informar ao Oracle qual operador você está utilizando.Você também pode usar o padrão SQL92 para JOIN usando as palavras RIGHT OUTER JOIN e LEFT OUTER JOIN.
Mostrarei isso mais a frente no segundo post.
A explicação sobre de qual lado utilizar é simples:
Se a coluna que contém os dados nulos é a da direita você então coloca o sinal (+) na coluna da esquerda e vice-versa.
Ex. Nas tabelas A e B existe a coluna ID do tipo NUMBER.
Na tabela A existe uma linha em que a coluna ID é nula,mas mesmo assim você precisa trazer esta linha na sua query ,neste caso você precisar fazer um JOIN para obtê - las.
ex.
select
from tabela1 A,tabela2 B
where A.id = B.id(+) ;
No exemplo acima foi feito um LEFT JOIN pois quero retornar todos os dados da tabela A que não satisfazem a condição da JOIN .
Criando as tabelas de exemplo :
dbajcc@DBPOST on 23-FEB-10 >create table jcc_join_a (seq number(2) , text varchar2(10)) ; 2 3 Table created. Elapsed: 00:00:00.03 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_a values(1,'disk1') ; 2 1 row created. Elapsed: 00:00:00.02 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_a values(2,'disk2') ; 2 1 row created. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_a(seq) values(3) ; 2 1 row created. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 >commit ; Commit complete. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 > create table jcc_join_b (seq number(2) , text varchar2(10)) ; 2 3 Table created. Elapsed: 00:00:00.02 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_b values(1,'disk1') ; 2 1 row created. Elapsed: 00:00:00.01 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_b values(2,'disk2') ; 2 1 row created. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 > insert into jcc_join_b(text) values('disk3') ; 2 1 row created. Elapsed: 00:00:00.00 dbajcc@DBPOST on 23-FEB-10 > |
Fazendo um RIGHT JOIN :
dbajcc@DBPOST on 23-FEB-10 >select a.* ,b.* from jcc_join_a a, jcc_join_b b where a.seq(+) = b.seq ; 2 3 4 SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 disk3 Elapsed: 00:00:00.02 dbajcc@DBPOST on 23-FEB-10 > |
Ou usando a sintaxe do padrão SQL92 :
dbajcc@DBPOST on 24-FEB-10 >select a.* ,b.* 2 from jcc_join_a a right outer join jcc_join_b b 3 on a.seq = b.seq ; SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 disk3 Elapsed: 00:00:00.00 dbajcc@DBPOST on 24-FEB-10 > |
Acima destaquei em azul a coluna na qual é o alvo e que por sinal contém um campo SEQ nulo para o campo TEXT "disk3" .
Agora vamos fazer um LEFT JOIN :
[oracle@marte ~]$ sqlplus dbajcc SQL*Plus: Release 11.2.0.1.0 Production on Wed Feb 24 07:49:02 2010 Copyright (c) 1982, 2009, Oracle. All rights reserved. Enter password: Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options dbajcc@DBPOST on 24-FEB-10 > select a.* ,b.* from jcc_join_a a, jcc_join_b b where a.seq = b.seq(+) ; 2 3 4 SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 3 Elapsed: 00:00:00.05 dbajcc@DBPOST on 24-FEB-10 > |
Ou usando o outro tipo de sintaxe :
dbajcc@DBPOST on 24-FEB-10 >select a.* ,b.* 2 from jcc_join_a a left outer join jcc_join_b b 3 on a.seq = b.seq ; SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 3 Elapsed: 00:00:00.19 dbajcc@DBPOST on 24-FEB-10 > |
Temos uma outra opção que é usar a um FULL OUTER JOIN para trazer os dados que não satisfazem a condição de JOIN das duas tabelas envolvidas.
dbajcc@DBPOST on 24-FEB-10 >select a.* ,b.* 2 from jcc_join_a a full outer join jcc_join_b b 3 on a.seq = b.seq ; SEQ TEXT SEQ TEXT ---------- ---------- ---------- ---------- 1 disk1 1 disk1 2 disk2 2 disk2 disk3 3 Elapsed: 00:00:00.01 dbajcc@DBPOST on 24-FEB-10 > |
Nem vou trazer exemplos sobre Cartesian Join pois acredito ser de pouca utilidade.
Até,
Júlio César Corrêa
Marcadores:
11gr2,
oracle,
outer join.left join,
right join,
sql
Subscribe to:
Posts (Atom)
