【发布时间】:2017-07-05 07:53:29
【问题描述】:
我有两个表,分别称为 Employee(列:Id、Name)和 DataSource(列:Id、EmployeeId、DataSourceName)。
每个员工都可以导出到零个或多个数据源并想象以下情况:
员工表
+----+-------------+
| Id | Name |
+----+-------------+
| 1 | Ivan |
| 2 | Adam |
+----+-------------+
数据源表:
+----+---------------------------------+
| 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
内部选择:
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'
在开始对它们进行基准测试之前,我想问一下我是否应该考虑更多方法(并且可能表现良好)。能否请您分享您对最佳性能查询的想法。
【问题讨论】:
-
您必须只进行测试,但是 WHERE NOT EXISTS “应该”更快,因为它不需要进行完全连接并且可以提前退出......但这将取决于一些因素,所以你真的需要测试
-
我想是的,我们也可以在找到第一条记录后退出(通过使用 SELECT TOP 1) - 这也可能适用于 WHERE NOT EXISTS
-
如果在NOT EXIST()中使用select,则不需要使用TOP 1,找到一条记录后会自动停止
-
我的意思是在顶部查询中使用 TOP 1 而不是在嵌套查询中,因此它声明:SELECT TOP 1 Employee.Id FROM Employee WHERE NOT EXIST ...
标签: sql-server performance database-performance query-performance