Найбільша відмінність не в тому, щоб приєднатись до не існує, це (як написано) SELECT *
.
На першому прикладі, ви отримуєте всі стовпці як A
і B
, в той час як у другому прикладі, ви отримаєте тільки стовпці A
.
У SQL Server другий варіант трохи швидше на дуже простому надуманому прикладі:
Створіть дві зразкові таблиці:
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
Вставте 10 000 рядків у кожну таблицю:
INSERT INTO dbo.A DEFAULT VALUES;
GO 10000
INSERT INTO dbo.B DEFAULT VALUES;
GO 10000
Видаліть кожен другий ряд з другої таблиці:
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;
Виконайте два SELECT
варіанти тесту :
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);
Плани виконання:
У другому варіанті не потрібно виконувати операцію фільтра, оскільки він може використовувати лівий оператор анти-напівз'єднання.
WHERE A.idx NOT IN (...)
є НЕ тотожний внаслідок тривалентного поведінкиNULL
(тобтоNULL
НЕ дорівнюєNULL
( і НЕ неравен), тому якщо у вас є якийсь - небудьNULL
вtableB
вас отримають несподівані результати!)