Największą różnicą jest to, że łączenie nie istnieje, to (jak napisano) SELECT *
.
W pierwszym przykładzie, można uzyskać wszystkie kolumny z obu A
i B
, podczas gdy w drugim przykładzie, można uzyskać tylko z kolumn A
.
W SQL Server drugi wariant jest nieco szybszy w bardzo prostym wymyślonym przykładzie:
Utwórz dwie przykładowe tabele:
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
Wstaw 10 000 wierszy do każdej tabeli:
INSERT INTO dbo.A DEFAULT VALUES;
GO 10000
INSERT INTO dbo.B DEFAULT VALUES;
GO 10000
Usuń co 5 rząd z drugiej tabeli:
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;
Wykonaj dwa SELECT
warianty instrukcji testowych :
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);
Plany realizacji:
Drugi wariant nie musi wykonywać operacji filtrowania, ponieważ może korzystać z lewego operatora anty-semi join.
WHERE A.idx NOT IN (...)
jest nie identyczne ze względu na zachowanie trójwartościowegoNULL
(czyliNULL
nie jest równyNULL
(ani nierówne), dlatego jeśli którykolwiekNULL
ztableB
was dostanie nieoczekiwane rezultaty!)