No passado, havia muita paranóia por aí IN
. Em particular, lembro-me de afirmações de que pode ser otimizado de forma diferente de um equivalente WHERE EXISTS
. Esta afirmação ainda é verdadeira? Ou agora é garantido que IN
e WHERE EXISTS
sempre dará os mesmos planos de execução nos casos em que as duas consultas são logicamente equivalentes?
Estou falando de consultas do seguinte formato
SELECT [...] FROM [FOO] WHERE [FOO_ID] IN (SELECT [FOO_ID] FROM [BAR])
-- Is logically equivalent to...
SELECT [...] FROM [FOO] WHERE EXISTS (SELECT 1 FROM [BAR] WHERE [BAR].[FOO_ID] = [FOO].[FOO_ID])
Não que eu não esteja falando sobre NOT IN
, NOT EXISTS
ou usando múltiplas IN
cláusulas.
A afirmação ainda é verdadeira, mas sempre foi uma preocupação para longas listas de expressões codificadas
IN
. O problema está principalmente no tempo extra de compilação, embora também possam resultar planos de consulta estranhos, devido ao fato de serem compilados em muitasOR
cláusulas.Seu exemplo é diferente: ele usa uma
IN
subconsulta, que é transformada numa fase inicial em uma semi-join, que é semelhante a umaEXISTS
qualquer maneira. O tempo de compilação deve ser praticamente o mesmo, e você pode ver por si mesmo neste violino que os planos de consulta são idênticos, independentemente de as tabelas estarem indexadas ou não.Sim, os planos nem sempre são idênticos, mas isso geralmente é o resultado do fato de você estar obtendo uma nova compilação, onde o otimizador não consegue decidir entre dois planos ruins (você também pode conseguir isso recompilando a mesma consulta). Se um bom método de acesso estiver disponível na subconsulta, espere que os planos sejam geralmente idênticos.