Desempenho do SQL JOIN vs IN?

164

Tenho um caso em que o uso de um JOIN ou IN me fornecerá os resultados corretos ... Qual normalmente tem melhor desempenho e por quê? Quanto isso depende de qual servidor de banco de dados você está executando? (Para sua informação, estou usando o MSSQL)

Polaris878
fonte
:) Eu estava realmente procurando um artigo diferente eu usei quando eu pesquisei em algo semelhante há um tempo atrás, e tropeçou em que um por engano
AdaTheDev
Desculpem a possível enganar ... não encontrou essa pergunta quando eu estava procurando
Polaris878

Respostas:

196

De um modo geral, INe JOINsã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 b.colseja único.

No entanto, este é 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 junção estiver UNIQUEmarcada e assim, ambas as consultas produzirão o mesmo plano SQL Server.

Caso contrário, INé mais rápido do que JOINligado DISTINCT.

Veja este artigo no meu blog para obter detalhes de desempenho:

Quassnoi
fonte
Sim, faz sentido que eles iriam executar o mesmo se a coluna se juntar é único (que é no meu caso)
Polaris878
1
Em uma nota semelhante, devo usar IN (SELECT DISTINCT ...) ou simplesmente IN (SELECT ...)?
moo
8
@ orlandu63: INimplica DISTINCT. SQL Serveré inteligente o suficiente para notá-lo e irá gerar os mesmos planos para as duas consultas. Não tenho certeza, no entanto, de como os outros RDBMSse comportarão.
Quassnoi 29/07/2009
>> IN e JOIN são consultas diferentes que podem gerar resultados diferentes. Você pode explicar por que isso geraria resultados diferentes nesse caso, mesmo que b.col não seja exclusivo?
Abhijeet
explainextended.com/2009/06/16/in-vs-join-vs-exists Realmente me ajuda .. Obrigado ..
Abbas Galiyakotwala
6

Isso é bastante difícil de dizer - para realmente descobrir qual funciona melhor, você precisa determinar o tempo de execução.

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

Porém, assim que você começar a usar OUTER JOIN, ou se não houver índices de chave estrangeira, a entrada poderá ser mais rápida.

Marc

marc_s
fonte
Eu estava pensando isso também ... porque parece que JOIN é um caso mais comum e provavelmente seria otimizado #
Polaris878
4

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, assumindo que as relações e os índices sejam mantidos, um Join terá um desempenho melhor no geral (mais esforço será necessário para trabalhar com essa operação do que com outros). Se você pensar conceitualmente, é a diferença entre 2 consultas e 1 consulta.

Você precisa conectá-lo ao Query Analyzer e experimentar e ver a diferença. Observe também o Plano de execução de consulta e tente minimizar as etapas.

AdamSane
fonte
4

Este tópico é bastante antigo, mas ainda é mencionado com frequência. Para meu gosto pessoal, é um pouco incompleto, porque existe outra maneira de perguntar ao banco de dados com a palavra-chave EXISTS, que eu achei mais rápida com mais frequência.

Portanto, se você estiver interessado apenas nos valores da tabela a, poderá usar esta consulta:

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

A diferença pode ser grande se col não estiver indexado, porque o banco de dados não precisa encontrar todos os registros em b que tenham o mesmo valor em col, mas apenas o primeiro. Se não houver índice no b.col e muitos registros na varredura de tabela ba puderem ser a consequência. Com IN ou JOIN, essa seria uma verificação completa da tabela; com EXISTS, isso seria apenas uma verificação parcial da tabela (até que o primeiro registro correspondente seja encontrado).

Se houver muitos registros em b com o mesmo valor de col, você também gastará muita memória ao 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.

Muitas vezes encontrei EXISTS mais rápido que IN, mesmo que exista um índice. Depende do sistema de banco de dados (o otimizador), dos dados e, por último, do tipo de índice usado.

S.Roeper
fonte
3
No MSSql, o fato de existir é melhor que um IN não parece verdadeiro. Para obter mais informações: explainextended.com/2009/06/16/in-vs-join-vs-exists Aqui você pode ler o seguinte: "Muitos pensam que EXISTS é mais eficiente que IN, porque EXISTS retorna apenas uma linha. não é verdade para o SQL Server. Como podemos ver nos exemplos acima, EXISTS e IN produz exatamente os mesmos planos. Isso ocorre porque EXISTS é mais flexível que IN. Um IN sempre pode ser reescrito como EXISTS (usando uma condição WHERE simples com um equijoin ) mas não vice-versa. "
Micaël Félix 10/03/2014
3

A implementação de cada banco de dados, mas você provavelmente pode adivinhar que todos eles resolvem problemas comuns mais ou menos da mesma maneira. Se você estiver usando o MSSQL, consulte o plano de execução gerado. Você pode fazer isso ativando os planos de criação de perfil e execuções. Isso fornecerá uma versão em texto quando você executar o comando.

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

Dê uma olhada no plano de execução. Na medida do possível, evite varreduras de tabelas, a menos que sua tabela seja pequena; nesse caso, uma varredura de tabela é mais rápida do que usar um índice. Leia as diferentes operações de junção que cada cenário diferente produz.

uriDium
fonte
1

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

Joel Coehoorn
fonte
5
Deveria fazer? Talvez. Faz isso? Não. Veja meu post.
314 cletus