A maior diferença não está na junção vs não existe, é (como está escrito), o SELECT *
.
No primeiro exemplo, você obtém todas as colunas de ambos A
e B
, enquanto no segundo exemplo, obtém apenas colunas de A
.
No SQL Server, a segunda variante é um pouco mais rápida em um exemplo artificial muito simples:
Crie duas tabelas de amostra:
CREATE TABLE dbo.A
(
A_ID INT NOT NULL
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
);
CREATE TABLE dbo.B
(
B_ID INT NOT NULL
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
);
GO
Insira 10.000 linhas em cada tabela:
INSERT INTO dbo.A DEFAULT VALUES;
GO 10000
INSERT INTO dbo.B DEFAULT VALUES;
GO 10000
Remova a cada quinta linha da segunda tabela:
DELETE
FROM dbo.B
WHERE B_ID % 5 = 1;
SELECT COUNT(*) -- shows 10,000
FROM dbo.A;
SELECT COUNT(*) -- shows 8,000
FROM dbo.B;
Execute as duas SELECT
variantes da instrução de teste :
SELECT *
FROM dbo.A
LEFT JOIN dbo.B ON A.A_ID = B.B_ID
WHERE B.B_ID IS NULL;
SELECT *
FROM dbo.A
WHERE NOT EXISTS (SELECT 1
FROM dbo.B
WHERE b.B_ID = a.A_ID);
Planos de execução:
A segunda variante não precisa executar a operação de filtro, pois pode usar o operador de junção anti-semifacial esquerda.
WHERE A.idx NOT IN (...)
é não idênticas devido ao comportamento trivalente deNULL
(ou seja,NULL
não é igual aNULL
(nem desigual), portanto, se você tiver qualquerNULL
emtableB
que você vai obter resultados inesperados!)