我很想知道在sql上查询排除的最有效方法。例如。有2个表(tableA和tableB)可以在1列(col1)上连接。我想为tableB中不存在col1的所有行显示tableA的数据。
(换句话说,tableB包含tableA的col1的子集。我想显示没有tableB中存在的数据的tableA)
假设tableB有100行,而tableA是巨大的(超过1M行)。我知道'不在(不存在)'可以使用,但也许有更有效的方法(更少的比较时间)来做它。我不喜欢外连接吗?
非常感谢代码段和评论。
答案 0 :(得分:7)
取决于RDBMS。对于Microsoft SQL Server NOT EXISTS is preferred到OUTER JOIN,因为它可以使用更有效的Anti-Semi连接。
对于Oracle Minus is apparently preferred而不是EXISTS(在合适的地方)
您需要查看执行计划并决定。
答案 1 :(得分:3)
我更喜欢使用
Select a.Col1
From TableA a
Left Join TableB b on a.Col1 = b.Col1
Where b.Col1 Is Null
我相信这会更快,因为你正在使用FK约束(假设你有 他们当然)
示例数据:
create table #a
(
Col1 int
)
Create table #b
(
col1 int
)
insert into #a
Values (1)
insert into #a
Values (2)
insert into #a
Values (3)
insert into #a
Values (4)
insert into #b
Values (1)
insert into #b
Values (2)
Select a.Col1
From #a a
Left Join #b b on a.col1 = b.Col1
Where b.Col1 is null
答案 2 :(得分:1)
已多次询问这些问题。通常最快的方法是:
SELECT * FROM table1
WHERE id in (SELECT id FROM table1 EXCEPT SELECT id FROM table2)
由于整个连接可以在索引上完成,因此使用NOT IN通常不能。
答案 3 :(得分:0)
这个问题没有正确的答案。每个RDBMS都有查询优化器,它将根据可用索引,表统计信息(行数,索引选择性),连接条件,查询条件等来确定最佳执行计划......
如果你的问题中有相对简单的查询,通常有几种方法可以在SQL中获得结果。每个尊重RDBMS的人都会认识到你的意图并创建相同的执行计划,无论你使用哪种语法(使用IN或EXISTS运算符的子查询,使用JOIN查询,......)
所以,这里最好的解决方案是编写最简单的查询,然后检查执行计划 如果该解决方案不可接受,那么您应该尝试找到更好的查询。