一尘不染

使用 LEFT JOIN 或 NOT EXISTS 之间的最佳实践

sql

使用 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)

我在 Access 中对 SQL Server 数据库使用查询。


阅读 76

收藏
2022-10-25

共1个答案

一尘不染

最大的区别不在于加入与不存在,它是(如所写)SELECT *,.

在第一个示例中,您从 和 中获取所有列 AB在第二个示例中,您仅从 中获取列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);

执行计划:

在此处输入图像描述

第二个变体不需要执行过滤操作,因为它可以使用左反半连接运算符。

2022-10-25