Parece-me que você pode fazer a mesma coisa em uma consulta SQL usando NOT EXISTS, NOT IN ou LEFT JOIN WHERE IS NULL. Por exemplo:
SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2)
SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a)
SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL
Não tenho certeza se tenho toda a sintaxe correta, mas estas são as técnicas gerais que já vi. Por que eu escolheria usar um sobre o outro? O desempenho difere ...? Qual destes é o mais rápido / mais eficiente? (Se depender da implementação, quando eu usaria cada um?)
EXISTS
cláusula. Você pode retornar*
,NULL
ou o que for: tudo isso será otimizado.SELECT
eFROM
. E*
é apenas mais fácil digitar. Sim,SQL
tem alguma semelhança com uma linguagem natural, mas é analisada e executada por uma máquina, uma máquina programada. Não é que ele de repente entre no seu cubículo e grite "pare de exigir os campos extras em umaEXISTS
consulta, porque eu estou cansado de analisá-los e depois jogá-los fora!". Está tudo bem com um computador, realmente.Respostas:
NOT IN vs. NOT EXISTS vs. LEFT JOIN / É NULL: SQL Server
NOT IN vs. NOT EXISTS vs. LEFT JOIN / É NULL: PostgreSQL
NOT IN vs. NOT EXISTS vs. LEFT JOIN / É NULL: Oracle
NOT IN vs. NOT EXISTS vs. LEFT JOIN / É NULL: MySQL
Em poucas palavras:
NOT IN
é um pouco diferente: nunca corresponde se houver apenas umNULL
na lista.Em
MySQL
,NOT EXISTS
é um pouco menos eficienteEm
SQL Server
,LEFT JOIN / IS NULL
é menos eficienteEm
PostgreSQL
,NOT IN
é menos eficienteEm
Oracle
, todos os três métodos são os mesmos.fonte
table1 .a
contiver,NULL
aEXISTS
consulta não retornará esta linha, mas aNOT IN
consulta setable2
estiver vazia. NOT IN vs. NOT EXISTS Colunas anuláveis: SQL ServerNULL NOT IN ()
avalia como verdadeiro (nãoNULL
), assim comoNOT EXISTS (NULL = column)
NOT EXISTS
sempre retornará a linha, masNOT IN
somente o fará se a subconsulta não retornar nenhuma linha.Se o banco de dados é bom para otimizar a consulta, os dois primeiros serão transformados em algo próximo ao terceiro.
Para situações simples como as que você pergunta, deve haver pouca ou nenhuma diferença, pois todas serão executadas como junções. Em consultas mais complexas, o banco de dados pode não conseguir fazer uma junção das consultas
not in
enot exists
. Nesse caso, as consultas ficarão muito mais lentas. Por outro lado, uma associação também pode ter um desempenho ruim se não houver um índice que possa ser usado; portanto, apenas porque você usa uma associação não significa que você está seguro. Você precisaria examinar o plano de execução da consulta para saber se pode haver algum problema de desempenho.fonte
Supondo que você esteja evitando nulos, são todas as formas de escrever uma anti-junção usando o SQL padrão.
Uma omissão óbvia é o equivalente usando
EXCEPT
:Observe no Oracle que você precisa usar o
MINUS
operador (sem dúvida um nome melhor):Falando em sintaxe proprietária, também pode haver equivalentes não-padrão que valem a pena investigar, dependendo do produto que você está usando, por exemplo,
OUTER APPLY
no SQL Server (algo como):fonte
Quando for necessário inserir dados na tabela com chave primária de vários campos, considere que será muito mais rápido (tentei no Access, mas acho que em qualquer banco de dados) não verificar se "não existem registros com 'tais' valores na tabela", - basta inserir na tabela e os registros em excesso (pela tecla) não serão inseridos duas vezes.
fonte
A perspectiva de desempenho sempre evita o uso de palavras-chave inversas como NOT IN, NOT EXISTS, ... Porque para verificar os itens inversos, o DBMS precisa executar todas as opções disponíveis e soltar a seleção inversa.
fonte
NOT
?