最大の違いは、結合と存在ではなく、(書かれているように)SELECT *
です。
最初の例では、あなたからすべての列を取得し、両方 A
とB
第二の例では、あなたから列のみを取得するのに対し、A
。
SQL Serverでは、2番目のバリアントは非常に単純な不自然な例でわずかに高速です。
2つのサンプルテーブルを作成します。
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
2番目のテーブルから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;
2つのテスト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);
実行計画:
2番目のバリアントは、左の反準結合演算子を使用できるため、フィルター操作を実行する必要はありません。
WHERE A.idx NOT IN (...)
ありません、同一原因の三価の動作にNULL
(つまり、NULL
等しくないNULL
)(でも等しくない、したがって、あなたが持っている場合はいずれかをNULL
してtableB
、あなたの予期しない結果が得られます!)