使用LEFT JOIN或NOT EXISTS格式之间是否有最佳实践?
使用一个而不是另一个有什么好处?
如果没有,哪个应该是首选?
SELECT * FROM tableA A LEFT JOIN tableB B ON A.idx = B.idx WHERE B.idx IS NULL
SELECT * FROM tableA A WHERE NOT EXISTS (SELECT idx FROM tableB B WHERE B.idx = A.idx)
解决方法
最大的区别不在于连接vs不存在,它是(如编写的)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);
执行计划:
第二个变体不需要执行过滤操作,因为它可以使用左反半连接运算符.