我有两个名为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'
在开始对它们进行基准测试之前,我想问一下我是否应该考虑更多的方法(并且可能表现良好)。您可以分享您的想法,以获得最佳的性能查询。
答案 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过滤器作为连接的一部分。“