La differenza più grande non è nel join vs non esiste, è (come scritto), il SELECT *
.
Nel primo esempio, ottieni tutte le colonne da entrambi A
e B
, mentre nel secondo esempio, ottieni solo le colonne A
.
In SQL Server, la seconda variante è leggermente più veloce in un semplice esempio inventato:
Creare due tabelle di esempio:
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
Inserisci 10.000 righe in ogni tabella:
INSERT INTO dbo.A DEFAULT VALUES;
GO 10000
INSERT INTO dbo.B DEFAULT VALUES;
GO 10000
Rimuovi ogni 5a fila dalla seconda tabella:
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;
Eseguire le due SELECT
varianti dell'istruzione test :
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);
Piani di esecuzione:
La seconda variante non deve eseguire l'operazione di filtro poiché può utilizzare l'operatore anti-semi join sinistro.
WHERE A.idx NOT IN (...)
è non è identico a causa del comportamento di trivalenteNULL
(vale a direNULL
, non è uguale aNULL
(né disuguale), quindi se avete qualsiasiNULL
intableB
si ottengono risultati inaspettati!)