SQL JOIN vs IN desempenho?

Eu tenho um caso em que usando um JOIN ou um IN me dará os resultados corretos … Qual normalmente tem melhor desempenho e por quê? Quanto depende de qual servidor de database você está executando? (FYI eu estou usando o MSSQL)

De um modo geral, IN e JOIN são consultas diferentes que podem gerar resultados diferentes.

 SELECT a.* FROM a JOIN b ON a.col = b.col 

não é o mesmo que

 SELECT a.* FROM a WHERE col IN ( SELECT col FROM b ) 

, a menos que o b.col seja único.

No entanto, esse é o sinônimo da primeira consulta:

 SELECT a.* FROM a JOIN ( SELECT DISTINCT col FROM b ) ON b.col = a.col 

Se a coluna de união for UNIQUE e marcada como tal, essas duas consultas produzirão o mesmo plano no SQL Server .

Se não for, então IN é mais rápido que JOIN em DISTINCT .

Veja este artigo no meu blog para detalhes de desempenho:

  • IN vs JOIN vs. EXISTS

Engraçado você mencionar isso, eu fiz um post sobre este assunto.

Veja Oracle vs MySQL vs SQL Server: Agregação vs Joins

Resposta curta: você tem que testá-lo e bancos de dados individuais variam muito.

Isso é difícil de dizer – para realmente descobrir qual funciona melhor, você precisaria realmente analisar os tempos de execução.

Como regra geral, acho que se você tiver índices em suas colunas de chave estrangeira, e se você estiver usando apenas (ou principalmente) as condições INNER JOIN, então o JOIN será um pouco mais rápido.

Mas assim que você começar a usar OUTER JOIN, ou se você estiver faltando índices de chave estrangeira, o IN pode ser mais rápido.

Marc

Um artigo interessante sobre as diferenças lógicas: SQL Server: JOIN vs IN vs EXISTS – a diferença lógica

Tenho certeza de que, supondo que as relações e os índices sejam mantidos, um Join terá um desempenho geral melhor (mais esforços serão aplicados a essa operação do que a outros). Se você pensar sobre isso conceitualmente, então é a diferença entre 2 consultas e 1 consulta.

Você precisa conectá-lo ao Query Analyzer, experimentá-lo e ver a diferença. Consulte também o Plano de Execução de Consultas e tente minimizar as etapas.

A implementação de cada database, mas você provavelmente pode adivinhar que todos eles resolvem problemas comuns mais ou menos da mesma maneira. Se você estiver usando o MSSQL, dê uma olhada no plano de execução que é gerado. Você pode fazer isso ativando os planos de profiler e execução. Isto lhe dará uma versão de texto quando você executar o comando.

Não tenho certeza qual versão do MSSQL você está usando, mas você pode obter uma gráfica no SQL Server 2000 no analisador de consultas. Tenho certeza de que essa funcionalidade está à espreita em algum lugar no SQL Server Studio Manager em versões posteriores.

Dê uma olhada no plano de execução. Tanto quanto possível, evite varreduras de tabela, a menos que sua tabela seja pequena, caso em que uma varredura de tabela é mais rápida do que usando um índice. Leia as diferentes operações de junit que cada cenário diferente produz.

Esse Thread é bem antigo, mas ainda é mencionado com frequência. Para meu gosto pessoal, é um pouco incompleto, porque existe outra maneira de perguntar ao database a palavra-chave EXISTS, que achei ser mais rápida do que nunca.

Então, se você está interessado apenas em valores da tabela a, você pode usar esta consulta:

 SELECT a.* FROM a WHERE EXISTS ( SELECT * FROM b WHERE b.col = a.col ) 

A diferença pode ser enorme se col não estiver indexado, porque o database não precisa encontrar todos os registros em b que possuem o mesmo valor em col, ele só precisa encontrar o primeiro. Se não houver um índice no b.col e muitos registros na varredura da tabela podem ser a consequência. Com IN ou um JOIN, isso seria uma varredura completa da tabela, com EXISTS, isso seria apenas uma varredura parcial da tabela (até que o primeiro registro correspondente seja encontrado).

Se houver muitos registros em b que tenham o mesmo valor de col, você também desperdiçará muita memory para ler todos esses registros em um espaço temporário apenas para descobrir que sua condição está satisfeita. Com existe isso geralmente pode ser evitado.

Eu freqüentemente encontrei EXISTS mais rápido do que IN, mesmo que haja um índice. Depende do sistema de database (o otimizador), os dados e, finalmente, não menos importante sobre o tipo de índice que é usado.

O otimizador deve ser inteligente o suficiente para fornecer o mesmo resultado para consultas normais. Verifique o plano de execução e eles devem dar a mesma coisa. Se não, eu normalmente consideraria o JOIN mais rápido. Todos os sistemas são diferentes, portanto, você deve criar o perfil do código no seu sistema para ter certeza.