O MySQL, assim como todos os outros sistemas, exceto o SQL Server, pode otimizar LEFT JOIN
/IS NULL
retornar FALSE
assim que o valor correspondente for encontrado, e é o único sistema que se preocupou em documentar esse comportamento. […] Como o MySQL não é capaz de usar HASH
e MERGE
juntar algoritmos, o único que ANTI JOIN
ele é capaz é oNESTED LOOPS ANTI JOIN
[...]
Essencialmente, [ NOT IN
] é exatamente o mesmo plano que LEFT JOIN
/ IS NULL
usa, apesar de esses planos serem executados pelas diferentes ramificações do código e parecerem diferentes nos resultados de EXPLAIN
. Os algoritmos são de fato os mesmos e as consultas são concluídas ao mesmo tempo.
[...]
É difícil dizer o motivo exato de [queda de desempenho ao usar NOT EXISTS
] , pois essa queda é linear e não parece depender da distribuição de dados, número de valores nas duas tabelas etc., desde que os dois campos sejam indexados. Como existem três partes de código no MySQL que essencialmente fazem um trabalho, é possível que o código responsável EXISTS
faça algum tipo de verificação extra, o que leva mais tempo.
[...]
O MySQL pode otimizar todos os três métodos para fazer uma espécie de NESTED LOOPS ANTI JOIN
. […] No entanto, esses três métodos geram três planos diferentes, executados por três partes diferentes de código. O código que executa o EXISTS
predicado é cerca de 30% menos eficiente […]
É por isso que a melhor maneira de procurar valores ausentes no MySQL é usando um LEFT JOIN
/ IS NULL
ou NOT IN
melhor que NOT EXISTS
.
(ênfases adicionadas)