查找表A中没有记录的行A

时间:2017-07-05 07:53:30

标签: sql-server performance database-performance query-performance

我有两个名为Employee的表(列:Id,Name)和DataSource(列:Id,EmployeeId,DataSourceName)。

每个员工都可以导出到零个或多个数据源,并想象以下情况:

员工表

+----+-------------+
| Id | Name        |
+----+-------------+
| 1  | Ivan        |
| 2  | Adam        |
+----+-------------+

DataSource表:

+----+---------------------------------+
| Id | EmplpoyeeId   | DataSourceName  |
+----+---------------------------------+
| 1  | 1             | Source1         |
| 2  | 1             | Source2         |
| 3  | 2             | Source2         |
+----+---------------------------------+

我需要一个查询来确定哪个员工未导出到' Source1' (结果应该是' Adam'在这种情况下,因为他只被导出到' Source2'。

表Employee和DataSource可以有大量记录(数千)。

有一些技术可以确定它,我们需要找到性能最佳的技术。我想到的很少:

左加入:

SELECT Employee.Id 
FROM Employee 
LEFT JOIN DataSource ON DataSource.EmployeeId = Employee.Id AND DataSource.DataSourceName = 'Source1'
WHERE DataSource.Id IS NULL

INNER SELECT:

SELECT Employee.Id
FROM Employee
WHERE NOT EXIST (SELECT NULL FROM DataSource WHERE DataSource.EmployeeId = Employee.Id AND DataSource.DataSourceName = 'Source1')

例外:

SELECT Employee.ID 
FROM Employee

EXCEPT

SELECT Employee.Id 
FROM Employee 
INNER JOIN DataSource ON DataSource.EmployeeId = Employee.Id AND DataSource.DataSourceName = 'Source1'

在开始对它们进行基准测试之前,我想问一下我是否应该考虑更多的方法(并且可能表现良好)。您可以分享您的想法,以获得最佳的性能查询。

1 个答案:

答案 0 :(得分:1)

如果您需要进一步阅读该主题,那么这篇文章是好的;

http://www.sqlinthewild.co.za/index.php/2010/03/23/left-outer-join-vs-not-exists/

它表明NOT EXISTS表现更好,因为它不需要完成完全连接(反半连接而不是半连接);

“这就是这两者之间的主要区别。当使用LEFT OUTER JOIN ... IS NULL技术时,SQL无法判断你只是在检查是否存在非限制性。优化器不够智能(还)。因此它确实如此。完整的连接然后过滤.NOT EXISTS过滤器作为连接的一部分。“