1

我在本地机器上有两个数据库,连接到localhost. 它们每个都有大约 200 万行。我正在执行以下非常简单的连接,并且花了一分钟多的时间才能完成。

select distinct x.patid
    from [i 3 sci study].dbo.clm_extract as x
    left join [i 3 study].dbo.claims as y on y.patid=x.patid
    where y.patid is null

当我查看执行计划时,我看到 join showplan 操作员有这样的说法 在此处输入图像描述

与两个表中的实际行数相比,为什么实际行数如此之高?

4

1 回答 1

3

LEFT JOIN左侧的每一行与右侧的每一行匹配,然后过滤。假设patid在任一表中都不是唯一的,则可能的匹配组合的数量可能会非常高。

尝试以下操作:

SET NOCOUNT ON;
GO
CREATE TABLE #t1 (Id INT NOT NULL);
CREATE TABLE #t2 (Id INT NOT NULL);
GO

INSERT #t1 (Id)
VALUES (1);
GO 100

INSERT #t2 (Id)
SELECT Id FROM #t1;
GO

现在看一下左连接查询表单的执行计划:

SELECT *
FROM #t1
LEFT OUTER JOIN #t2 ON #t1.Id = #t2.Id
WHERE #t2.Id IS NULL;

查看执行计划,散列连接显示 10,000 个实际行(100 来自 #t1 x 100 来自 #t2)。这显示了使用以下任何 T-SQL 语法检查是否存在(或不存在)的优势:

SELECT #t1.Id
FROM #t1
WHERE NOT EXISTS (SELECT * FROM #t2 WHERE Id = #t1.Id);

-- #t2.Id must not contain any NULLs for this to be correct
SELECT #t1.Id
FROM #t1
WHERE Id NOT IN (SELECT #t2.Id FROM #t2);

-- Returns DISTINCT #t1 values
SELECT Id
FROM #t1
EXCEPT
SELECT Id 
FROM #t2;

检查是否存在使发动机短路。这是由于反半连接。一旦找到第一个匹配项,它就会移动到下一个记录。有关更多详细信息,请参阅此博客文章

于 2012-10-30T17:21:18.200 回答