我有两个表机构和结果,我想看看机构是否有任何结果我可以排除那些没有结果的结果。
使用JOIN或使用EXISTS可以获得更好的性能吗?
谢谢你,
-Nimesh
答案 0 :(得分:18)
根据语句,统计信息和数据库服务器,它可能没有区别 - 可能会生成相同的优化查询计划。
基本上有三种方式可以将DB连接到桌面下面:
嵌套循环 - 一个比第二个大得多的表。检查较小表中的每一行是否有较大的每一行。
合并 - 对于同一排序顺序的两个表。两者都按顺序运行并匹配它们对应的位置。
哈希 - 其他一切。临时表用于建立匹配。
通过使用exists,您可以有效地强制查询计划执行嵌套循环。这可能是最快捷的方式,但实际上您需要查询计划程序来决定。
我想说你需要编写两个SQL语句并比较查询计划。根据您拥有的数据,您可能会发现它们的变化很大。
例如,如果[INSTIT]和[Results]的大小相似,并且两者都集中在InstitutionID上,那么合并连接将是最快的。如果[Results]比[INSTIT]大得多,嵌套循环可能会更快。
答案 1 :(得分:14)
取决于。
最终,2服务完全不同。
您加入2个表来访问相关记录。如果您不需要访问相关记录中的数据,则无需加入它们。
EXISTS可用于确定令牌是否存在于给定数据集中,但不允许您访问相关记录。
发布您想到的两种方法的示例,我可能会给您一个更好的主意。
使用您的两个表机构和结果如果您想要一个有结果的机构列表,这个查询将是最有效的:
select Institutions.institution_name
from Institutions
inner join Results on (Institutions.institution_id = Results.institution_id)
如果您有institution_id并且只想知道它是否有结果,那么使用EXISTS可能会更快:
if exists(select 1 from Results where institution_id = 2)
print "institution_id 2 has results"
else
print "institution_id 2 does not have results"
答案 2 :(得分:5)
这取决于你的优化器。我在Oracle 10g和11g中尝试了以下两个。在10克,第二个稍快。在11克,他们是相同的。
然而,#1实际上是对EXISTS条款的滥用。使用联接查找匹配项。
select *
from
table_one t1
where exists (
select *
from table_two t2
where t2.id_field = t1.id_field
)
order by t1.id_field desc
select t1.*
from
table_one t1
,table_two t2
where t1.id_field = t2.id_field
order by t1.id_field desc
答案 3 :(得分:4)
无论是否存在性能差异,您都需要使用更适合您的目的。您的目的是获取机构列表(不是结果 - 您不需要额外的数据)。因此,选择没有结果的机构......翻译 - 使用EXISTS。
答案 4 :(得分:3)
我说JOIN速度较慢,因为一旦EXISTS调用找到了某些内容,查询就会停止,而JOIN会一直持续到最后。
编辑:但这取决于查询。这应该根据具体情况来判断。
答案 5 :(得分:1)
您是否将EXISTS用作相关子查询的一部分?如果是这样,连接几乎总是更快。
您的数据库应该有基准查询的方法。使用它们来查看哪个查询运行得更快。
答案 6 :(得分:1)
实际上,根据您对问题的模糊描述,听起来像NOT IN查询是最明显的编码方式:
SELECT *
FROM Institutions
WHERE InstitutionID NOT IN (
SELECT DISTINCT InstitutionID
FROM Results
)
答案 7 :(得分:1)
LEFT OUTER JOIN往往比NOT EXISTS **表现更好,但在你的情况下你想要做EXISTS并且使用简单的INNER JOIN并不能完全复制EXISTS行为。如果您有多个机构的结果,则执行INNER JOIN将为该机构返回多行。你可以通过使用DISTINCT解决这个问题,但是无论如何EXISTS可能会更好地表现。
**对于那些不熟悉这种方法的人:
SELECT
MyTable.MyTableID
FROM
dbo.MyTable T1
LEFT OUTER JOIN dbo.MyOtherTable T2 ON
T2.MyTableID = T1.MyTableID
WHERE
T2.MyOtherTableID IS NULL
相当于
SELECT
MyTable.MyTableID
FROM
dbo.MyTable T1
WHERE NOT EXISTS (SELECT * FROM MyOtherTable T2 WHERE T2.MyTableID = T1.MyTableID)
假设MyOtherTableID是NOT NULL列。第一种方法通常比NOT EXISTS方法执行得更快。
答案 8 :(得分:1)
如果RESULTS表每INSTITUTION
行有多行,EXISTS()
的好处是不要求您选择不同的机构。
至于性能,我看到joins, IN(), and EXISTS()
在各种用途中都是最快的。要找到最适合您的方法,您必须进行测试。
答案 9 :(得分:1)
在上述情况下,Exists语句的工作速度比连接速度快。 存在将为您提供单一记录,也将节省时间。 在连接的情况下,记录的数量将更多,并且必须使用所有记录。
答案 10 :(得分:0)
如果您指的是使用左(或右)外连接或不存在子查询,我相当肯定左外连接在性能方面胜出。例如:
SELECT t1.* FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.id = t2.id WHERE t2.id IS NULL
上面应该比等效的子查询更快,如果你专门提到存在 - 那么,在结构允许的情况下,内连接将始终是首选选项。
答案 11 :(得分:0)
如果你想要那些没有结果的机构,那么'Where Not Exists'子查询会更快,因为一旦找到有结果的那个结果,它就会停止...
如果你想要机构有结果,但你实际上并不想要结果,同样的事情。使用“Where Exists”子查询..它会在找到单个结果后立即停止...这也可以确保结果集每个机构只有一个记录,而如果您有一个具有多个结果的机构,则使用加入方法需要您添加'distinct'关键字或'Group By'子句,以消除将从与单个机构匹配的多个Result记录中产生的重复cartesion产品行。
如果您需要结果,那么如果您不想看到没有结果的机构,请进行加入 - 内部加入;如果您想要查看所有机构,包括没有结果的机构,则进行外部联接。