Самая большая разница не в объединении против не существует, то (как написано), то 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
Удалить каждый 5-й ряд из второй таблицы:
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
вас получат неожиданные результаты!)