Atualização:
Este artigo no meu blog resume minha resposta e meus comentários a outras respostas e mostra os planos reais de execução:
SELECT *
FROM a
WHERE a.c IN (SELECT d FROM b)
SELECT a.*
FROM a
JOIN b
ON a.c = b.d
Essas consultas não são equivalentes. Eles podem gerar resultados diferentes se sua tabela
b não é preservada por chave (ou seja, os valores de b.d não são únicos). O equivalente da primeira consulta é o seguinte:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT d
FROM b
) bo
ON a.c = bo.d
Se
b.d é UNIQUE e marcado como tal (com um UNIQUE INDEX ou UNIQUE CONSTRAINT ), essas consultas são idênticas e provavelmente usarão planos idênticos, pois SQL Server é inteligente o suficiente para levar isso em conta. SQL Server pode empregar um dos seguintes métodos para executar esta consulta:-
Se houver um índice ema.c,déUNIQUEebé relativamente pequeno comparado aa, então a condição é propagada para a subconsulta e oINNER JOINsimples é usado (combconduzindo)
-
Se houver um índice emb.dednão éUNIQUE, então a condição também é propagada eLEFT SEMI JOINé usado. Também pode ser usado para a condição acima.
-
Se houver um índice em ambosb.dea.ce eles são grandes, entãoMERGE SEMI JOINé usado
-
Se não houver índice em nenhuma tabela, uma tabela de hash será construída embeHASH SEMI JOINé usado.
Nenhum desses métodos reavalia toda a subconsulta a cada vez.
Veja esta entrada no meu blog para mais detalhes sobre como isso funciona:
Existem links para todos os
RDBMS dos quatro grandes.