Inner Join ou Where - Qual o quot;melhorquot;?
Bom dia a todos.
Essa é uma dúvida que sempre me acompanhou. Sei das vantagens de se utilizar o Join no caso do left ou right e full. Porém no caso o Inner Join e do Where exite alguma diferença de performance em utilizar um outro tipo de relacionamento de tabela? Minha dúvida surgiu quando notei que o Código SQL Gerado pelo Access em suas consultas usa Join enquanto o código SQL Gerado pelo MsQuery utiliza Where, com isso deduzi que não há diferença de perfomance, mas gostaria da opinião dos colegas quanto a isso.
Abraço a todos.
Oberdan. :!:
Essa é uma dúvida que sempre me acompanhou. Sei das vantagens de se utilizar o Join no caso do left ou right e full. Porém no caso o Inner Join e do Where exite alguma diferença de performance em utilizar um outro tipo de relacionamento de tabela? Minha dúvida surgiu quando notei que o Código SQL Gerado pelo Access em suas consultas usa Join enquanto o código SQL Gerado pelo MsQuery utiliza Where, com isso deduzi que não há diferença de perfomance, mas gostaria da opinião dos colegas quanto a isso.
Abraço a todos.
Oberdan. :!:
Oberdan
Curtidas 0
Respostas
Afarias
30/09/2004
INNER JOIN é uma sintaxe mais moderna. É melhor por 2 pontos::
1- mais organizada e fácil de ler (para o desenvolvedor)
2- melhor para os otimizadores (dos bancos) achar o melhor plano de ação para a realização da consulta
Em geral não deve haver diferenças de performance entre as duas, mas contando com o ponto 2 citado acima, numa consulta mais complexa um ´otimizador´ poderia achar um plano melhor para o inner q para o where (mas isso não é para ocorrer)
T+
1- mais organizada e fácil de ler (para o desenvolvedor)
2- melhor para os otimizadores (dos bancos) achar o melhor plano de ação para a realização da consulta
Em geral não deve haver diferenças de performance entre as duas, mas contando com o ponto 2 citado acima, numa consulta mais complexa um ´otimizador´ poderia achar um plano melhor para o inner q para o where (mas isso não é para ocorrer)
T+
GOSTEI 0
Tnaires
30/09/2004
Eu convivi com uma melhoria prática usando JOINs em lugar d WHEREs. Uma vez, eu queria alterar um registro q uma consuita q eu fiz retornou (ela só tinha WHEREs). Na hora d gravar, dava erro, mas qdo eu substituí por JOINs, ele deixou eu alterar o registro.
GOSTEI 0
Isaiasbass
30/09/2004
Só aproveitando o tópico
Estou tendo um baita problema com performance na hora de pesquisa para relatórios.
Uso InterBase 6.0
São Joins onde só uso wheres e agora q fiz uma importação de uma base de mais de 100MB q tem tablas de cerca de 600 mil registros então os relatorios ficaram super lentos para exibição.
Queria um exmplo básico do Inner Join relacionando 3 ou mais tabelas para q eu posa fzer testes de performance.
Obrigado.
Estou tendo um baita problema com performance na hora de pesquisa para relatórios.
Uso InterBase 6.0
São Joins onde só uso wheres e agora q fiz uma importação de uma base de mais de 100MB q tem tablas de cerca de 600 mil registros então os relatorios ficaram super lentos para exibição.
Queria um exmplo básico do Inner Join relacionando 3 ou mais tabelas para q eu posa fzer testes de performance.
Obrigado.
GOSTEI 0
Afarias
30/09/2004
select {lista de campos} from tabela1 t1 inner join tabela2 t2 on (t1.campo_chave=t2.campo_chave) inner join tabela3 t3 on (t2.campo_chave=t3.campo_chave) {...} where {...}
por exemplo, selecionar todos os ítens (serviços) de ordens de serviço emitidas em determinada data, contendo número e data da ordem, nome do solicitante, informações do serviço -- segue o metadata (simplificado)
[solicitantes]
codigo
nome
[servicos]
codigo
descricao
[ordens]
numero
data
cod_solicitante
[itens]
num_ordem
cod_servico
select sol.nome, ser.descricao, ord.numero, ord.data from ordens ord inner join solicitantes sol on (sol.codigo=ord.cod_solicitante) inner join itens ite on (ite.num_ordem=ord.numero) inner join servicos ser on (ser.codigo=ite.cod_servico) where ord.data = :alguma_data
T+
GOSTEI 0
Aguiarle
30/09/2004
select {lista de campos} from tabela1 t1 inner join tabela2 t2 on (t1.campo_chave=t2.campo_chave) inner join tabela3 t3 on (t2.campo_chave=t3.campo_chave) {...} where {...}
select sol.nome, ser.descricao, ord.numero, ord.data from ordens ord inner join solicitantes sol on (sol.codigo=ord.cod_solicitante) inner join itens ite on (ite.num_ordem=ord.numero) inner join servicos ser on (ser.codigo=ite.cod_servico) where ord.data = :alguma_data
ao inves de usar o where, faco o filtro na propria juncao
select sol.nome, ser.descricao, ord.numero, ord.data from ordens ord inner join solicitantes sol on (sol.codigo=ord.cod_solicitante) inner join itens ite on (ite.num_ordem=ord.numero) inner join servicos ser on (ser.codigo=ite.cod_servico) and (ord.data = :alguma_data)
GOSTEI 0
Afarias
30/09/2004
|ao inves de usar o where, faco o filtro na propria juncao
Mas está errado. No mínimo conceitualmente errado.
A sintaxe do INNER JOIN procura justamente separar RELACAO de ´FILTRO´ (era tudo junto no WHERE) -- e vc pega e junta tudo no JOIN??
T+
Mas está errado. No mínimo conceitualmente errado.
A sintaxe do INNER JOIN procura justamente separar RELACAO de ´FILTRO´ (era tudo junto no WHERE) -- e vc pega e junta tudo no JOIN??
T+
GOSTEI 0
Paulo_amorim
30/09/2004
Olá
Só lembrando, essa sintaxe com JOIN não funciona em ORACLE antes da versão 9i , na qual ela foi implementada.
Nessas versões anteriores, a sintaxe de INNER JOIN deve ser feita no WHERE, bem como a de OUTER JOIN, que deve ser feita colocando ´(+)´ no campo de menor importância
Até+
Só lembrando, essa sintaxe com JOIN não funciona em ORACLE antes da versão 9i , na qual ela foi implementada.
Nessas versões anteriores, a sintaxe de INNER JOIN deve ser feita no WHERE, bem como a de OUTER JOIN, que deve ser feita colocando ´(+)´ no campo de menor importância
Até+
GOSTEI 0
Afarias
30/09/2004
É verdade, o Oracle só implementou a sintaxe ANSI-92 de joins recentemente.
T+
T+
GOSTEI 0
Aguiarle
30/09/2004
|ao inves de usar o where, faco o filtro na propria juncao
Mas está errado. No mínimo conceitualmente errado.
A sintaxe do INNER JOIN procura justamente separar RELACAO de ´FILTRO´ (era tudo junto no WHERE) -- e vc pega e junta tudo no JOIN??
T+
Nos testes q eu fiz o redimento do filtro na juncao das tabelas e consideravelmente notavel, pois ele monta a tabela filtrando o nao desejado. Ja com o where ele monta a tabela com todas as possibilidades de acordo com o join e depois faz esta filtragem do where. Pelo menos com no banco interbase eu notei isto.
GOSTEI 0
Afarias
30/09/2004
|Nos testes q eu fiz o redimento do filtro na juncao das tabelas e
|consideravelmente notavel,
Que versão do IB? Pode postar aqui um teste pático onde notou essa diferença??
Fiquei curioso pq eu nunca vi um plano de execução do IB 6.0 ou no FB 1.0 que se mostrase diferente entre as duas formas.
|Ja com o where ele monta a tabela com todas as possibilidades de
|acordo com o join e depois faz esta filtragem do where.
Não... depende do JOIN, tabelas envolvidas e tals... mas geralmente o WHERE é ´executado´ antes.
Um exemplo simples é::
select nota.data, item.produto, item.qtde
from nota inner join item on (item.nota = nota.numero)
where nota.vendedor = x
num banco contendo 1000 notas e apenas 10 do vendedor x, apenas 10 registros da tabela nota seriam lidos (10 reads em nota).
T+
|consideravelmente notavel,
Que versão do IB? Pode postar aqui um teste pático onde notou essa diferença??
Fiquei curioso pq eu nunca vi um plano de execução do IB 6.0 ou no FB 1.0 que se mostrase diferente entre as duas formas.
|Ja com o where ele monta a tabela com todas as possibilidades de
|acordo com o join e depois faz esta filtragem do where.
Não... depende do JOIN, tabelas envolvidas e tals... mas geralmente o WHERE é ´executado´ antes.
Um exemplo simples é::
select nota.data, item.produto, item.qtde
from nota inner join item on (item.nota = nota.numero)
where nota.vendedor = x
num banco contendo 1000 notas e apenas 10 do vendedor x, apenas 10 registros da tabela nota seriam lidos (10 reads em nota).
T+
GOSTEI 0
Aguiarle
30/09/2004
|Nos testes q eu fiz o redimento do filtro na juncao das tabelas e
|consideravelmente notavel,
Que versão do IB? Pode postar aqui um teste pático onde notou essa diferença??
Fiquei curioso pq eu nunca vi um plano de execução do IB 6.0 ou no FB 1.0 que se mostrase diferente entre as duas formas.
|Ja com o where ele monta a tabela com todas as possibilidades de
|acordo com o join e depois faz esta filtragem do where.
Não... depende do JOIN, tabelas envolvidas e tals... mas geralmente o WHERE é ´executado´ antes.
Um exemplo simples é::
select nota.data, item.produto, item.qtde
from nota inner join item on (item.nota = nota.numero)
where nota.vendedor = x
num banco contendo 1000 notas e apenas 10 do vendedor x, apenas 10 registros da tabela nota seriam lidos (10 reads em nota).
T+
faca um teste com tabelas q vc possua q contenham muitos registros e marque o tempo gasto nos dois casos.
no meu caso, eu tenho uma tabela de pedidos com registros consideraves que busca informacoes em outras duas tabelas menores,
quando eu tirei o where e coloquei o filtro no inner join ela me retornou um resultado melhor.
Ex:
select nota.data, item.produto, item.qtde
from nota inner join item on (item.nota = nota.numero) and (
nota.vendedor = x)
GOSTEI 0
Afarias
30/09/2004
|faca um teste com tabelas q vc possua q contenham muitos registros e
|marque o tempo gasto nos dois casos.
Já fiz isso. obtive os mesmos resultados.
|no meu caso, eu tenho uma tabela de pedidos com registros
|consideraves que busca informacoes em outras duas tabelas menores,
pode postar aqui o SQL (SELECT) para q eu possa constatar??
aproveita e me passa qual a versão do IB onde viu isso ocorrer.
|quando eu tirei o where e coloquei o filtro no inner join ela me retornou
|um resultado melhor.
Pois me passe esse SQL pq todos q testei não apresentaram isto (pode deixar q as tabelas eu ´simulo´ aqui)
T+
|marque o tempo gasto nos dois casos.
Já fiz isso. obtive os mesmos resultados.
|no meu caso, eu tenho uma tabela de pedidos com registros
|consideraves que busca informacoes em outras duas tabelas menores,
pode postar aqui o SQL (SELECT) para q eu possa constatar??
aproveita e me passa qual a versão do IB onde viu isso ocorrer.
|quando eu tirei o where e coloquei o filtro no inner join ela me retornou
|um resultado melhor.
Pois me passe esse SQL pq todos q testei não apresentaram isto (pode deixar q as tabelas eu ´simulo´ aqui)
T+
GOSTEI 0
Vinicius2k
30/09/2004
Colegas,
Acho que deve ser analisado também o lado dos índices...
Se o Tabela A tiver um índice de pior seletividade que a Tabela B, ou mesmo não contiver um índice para o campo do WHERE, caso a B tenha um índice bom, consequentemente o ´filtro´ aplicado sobre ela (B) terá performance superior... Estou errado?
Se, em teoria, as instruções deveriam responder com a mesma performance, a única possível explicação que vejo é esta.
Só verificando a analise do PLAN para comprovar essa suposição...
T+
Acho que deve ser analisado também o lado dos índices...
Se o Tabela A tiver um índice de pior seletividade que a Tabela B, ou mesmo não contiver um índice para o campo do WHERE, caso a B tenha um índice bom, consequentemente o ´filtro´ aplicado sobre ela (B) terá performance superior... Estou errado?
Se, em teoria, as instruções deveriam responder com a mesma performance, a única possível explicação que vejo é esta.
Só verificando a analise do PLAN para comprovar essa suposição...
T+
GOSTEI 0
Afarias
30/09/2004
|Acho que deve ser analisado também o lado dos índices...
Contando q estejamos tratando do mesmo campo (´filtro´), mudando apenas sua ´colocação´ dentro do SELECT, acho q a seletividade do índice não fará diferença -- admitindo q os índices necessários existam.
|Só verificando a analise do PLAN para comprovar essa suposição...
Por isso gostaria de ter o SQL, pq o normal (que tenho visto) é obter o mesmo plan para qualquer das situações.
T+
Contando q estejamos tratando do mesmo campo (´filtro´), mudando apenas sua ´colocação´ dentro do SELECT, acho q a seletividade do índice não fará diferença -- admitindo q os índices necessários existam.
|Só verificando a analise do PLAN para comprovar essa suposição...
Por isso gostaria de ter o SQL, pq o normal (que tenho visto) é obter o mesmo plan para qualquer das situações.
T+
GOSTEI 0
Kenshindigital
30/09/2004
se ele executou a mesma query primeiro após conectar o banco pela primeira vez usando where a query pode ter demorado porque não havia cache, a primeira query usando determinada tabela geralmente demora mais.
Tente testar novamente depois de o banco ter cacheado a tabela.
Tente testar novamente depois de o banco ter cacheado a tabela.
GOSTEI 0