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
éUNIQUE
eb
é relativamente pequeno comparado aa
, então a condição é propagada para a subconsulta e oINNER JOIN
simples é usado (comb
conduzindo)
-
Se houver um índice emb.d
ed
nã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.d
ea.c
e eles são grandes, entãoMERGE SEMI JOIN
é usado
-
Se não houver índice em nenhuma tabela, uma tabela de hash será construída emb
eHASH 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.