Portanto, IN não é igual a EXISTS nem produzirá o mesmo plano de execução.
Normalmente EXISTS é usado em uma subconsulta correlacionada, o que significa que você irá JUNTAR a consulta interna EXISTS à sua consulta externa. Isso adicionará mais etapas para produzir um resultado, pois você precisa resolver as junções de consulta externa e as junções de consulta interna e, em seguida, corresponder suas cláusulas where para unir ambas.
Normalmente IN é usado sem correlacionar a consulta interna com a consulta externa, e isso pode ser resolvido em apenas uma etapa (na melhor das hipóteses).
Considere isto:
Se você usar IN e o resultado da consulta interna for milhões de linhas de valores distintos, provavelmente terá um desempenho MAIS LENTO do que EXISTS, visto que a consulta EXISTS tem desempenho (tem os índices corretos para se juntar à consulta externa).
Se você usar EXISTS e a junção com sua consulta externa for complexa (leva mais tempo para ser executada, nenhum índice adequado), ela tornará a consulta mais lenta pelo número de linhas na tabela externa; às vezes, o tempo estimado para conclusão pode ser em dias. Se o número de linhas for aceitável para o hardware fornecido ou se a cardinalidade dos dados estiver correta (por exemplo, menos valores DISTINCT em um conjunto de dados grande) IN pode ser executado mais rápido do que EXISTS.
Todos os itens acima serão observados quando você tiver uma quantidade razoável de linhas em cada tabela (por justo, quero dizer algo que excede o processamento da CPU e / ou limites de memória ram para cache).
Portanto, a RESPOSTA é DEPENDE. Você pode escrever uma consulta complexa dentro de IN ou EXISTS, mas como regra geral, você deve tentar usar IN com um conjunto limitado de valores distintos e EXISTS quando você tem muitas linhas com muitos valores distintos.
O truque é limitar o número de linhas a serem verificadas.
Saudações,
MarianoC