我已经尝试了一些测试数据并找到了一种我认为更快的方法,USING THE EXCEPT OPERATOR
以下是我的发现。
测试数据
CREATE TABLE TestTable_1
(ID INT IDENTITY PRIMARY KEY,
Column1 INT,
Column2 INT
)
GO
CREATE TABLE TestTable_2
(ID INT IDENTITY PRIMARY KEY,
Column1 INT,
Column2 INT,
FK_ID INT references TestTable_1(ID)
)
GO
DECLARE @i INT = 1
WHILE (@i <= 10000)
BEGIN
INSERT INTO TestTable_1 (Column1, Column2)
VALUES (@i , @i + 100)
SET @i = @i + 1;
END
DECLARE @i2 INT = 1
WHILE (@i2 <= 10000)
BEGIN
INSERT INTO TestTable_2 (Column1, Column2, FK_ID)
VALUES (@i2 , @i2 + 100, 1 + CONVERT(INT, (10000-1+1)*RAND()))
SET @i2 = @i2 + 1;
END
UPDATE TestTable_2
SET FK_ID = NULL
WHERE ID IN (SELECT TOP 10 ID FROM TestTable_2 ORDER BY NEWID())
表二上的过滤索引
CREATE NONCLUSTERED INDEX FIX_FK_ID
ON TestTable_2(ID, FK_ID)
WHERE FK_ID IS NULL ;
GO
查询 1
SET STATISTICS IO ON;
PRINT 'TEST 1'
SELECT T1.*
FROM TestTable_1 T1 LEFT JOIN TestTable_2 T2
ON T1.ID = T2.FK_ID
WHERE FK_ID IS NOT NULL
查询 2
PRINT 'TEST 2'
SELECT ID, Column1, Column2 FROM TestTable_1
EXCEPT
SELECT ID, Column1, Column2 FROM TestTable_2
WHERE FK_ID IS NULL
TEST 1
(9990 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TestTable_1'. Scan count 1, logical reads 28, physical reads 0, read-ahead reads 19, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TestTable_2'. Scan count 1, logical reads 33, physical reads 3, read-ahead reads 29, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
TEST 2
(9990 row(s) affected)
Table 'TestTable_1'. Scan count 1, logical reads 28, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TestTable_2'. Scan count 1, logical reads 22, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
两个查询的执行计划