SQL JOIN vs IN性能?


164

在某些情况下,使用JOIN或IN将为我提供正确的结果...哪一种通常具有更好的性能,为什么?它在多大程度上取决于您正在运行的数据库服务器?(仅供参考,我正在使用MSSQL)


:)我实际上是在寻找我前一段时间研究类似内容时使用的另一篇文章,但偶然发现了该文章
AdaTheDev

抱歉,可能存在欺骗行为...当我搜索时没有找到该问题
Polaris878

Answers:


196

一般来说,INJOIN是可以产生不同结果的不同查询。

SELECT  a.*
FROM    a
JOIN    b
ON      a.col = b.col

与...不同

SELECT  a.*
FROM    a
WHERE   col IN
        (
        SELECT  col
        FROM    b
        )

,除非b.col是唯一的。

但是,这是第一个查询的同义词:

SELECT  a.*
FROM    a
JOIN    (
        SELECT  DISTINCT col
        FROM    b
        )
ON      b.col = a.col

如果联接列被UNIQUE标记为,则这两个查询在中产生相同的计划SQL Server

如果不是,则INJOINon 快DISTINCT

有关性能的详细信息,请参见我的博客中的这篇文章:


是的,如果
联接

1
类似地,我应该使用IN(SELECT DISTINCT ...)还是简单地使用IN(SELECT ...)?
moo

8
@ orlandu63:IN暗含DISTINCTSQL Server非常聪明,可以注意到它,并且将为两个查询生成相同的计划。不过,不确定其他RDBMS人的行为如何。
Quassnoi

>> IN和JOIN是不同的查询,它们可以产生不同的结果。你能解释一下为什么即使b.col不是唯一的,在这种情况下为什么会产生不同的结果吗?
阿披耶特(Abhijeet)2015年



6

这很难说-为了真正找出哪个更好,您需要实际分析执行时间。

作为一般经验法则,我认为如果您的外键列上有索引,并且如果仅(或主要)使用INNER JOIN条件,则JOIN会稍快一些。

但是,一旦您开始使用OUTER JOIN,或者如果您缺少外键索引,则IN可能会更快。

马克


我也在想这个……因为似乎JOIN是一个更常见的情况,并且更有可能被优化
Polaris878

4

关于逻辑差异的有趣文章:SQL Server:JOIN vs IN vs EXISTS-逻辑差异

我非常确定,假设保持关系和索引,Join的整体效果会更好(与其他操作相比,在该操作上投入更多的精力)。如果从概念上考虑它,那么它是2个查询和1个查询之间的区别。

您需要将其连接到查询分析器,然后尝试一下以查看区别。还要查看查询执行计划,并尝试最小化步骤。


4

这个主题很老,但仍然经常提及。就我个人的口味而言,它有点不完整,因为还有另一种方法可以使用EXISTS关键字查询数据库,我发现它经常更快。

因此,如果您仅对表a中的值感兴趣,则可以使用以下查询:

SELECT  a.*
FROM    a
WHERE   EXISTS (
    SELECT  *
    FROM    b
    WHERE   b.col = a.col
    )

如果不对col进行索引,则差异可能会很大,因为db不必查找b中具有col相同值的所有记录,而只需查找第一个记录。如果b.col上没有索引,则可能会导致ba表扫描中有很多记录。对于IN或JOIN,这将是全表扫描,对于EXISTS,这将仅是部分表扫描(直到找到第一个匹配记录)。

如果b中有很多记录具有相同的col值,那么您也会浪费大量内存将所有这些记录读入临时空间,只是为了发现您的条件得到满足。存在的情况通常可以避免。

即使有索引,我也经常发现EXISTS快于IN。它取决于数据库系统(优化器),数据,最后取决于所使用的索引类型。


3
在MSSql上,存在的事实胜于IN的事实似乎不成立。有关更多信息,请访问:explainextextended.com/2009/06/16/in-vs-join-vs-exists在这里您可以看到:“许多人认为EXISTS比IN更有效,因为EXISTS仅返回一行。这是从上面的示例中可以看出,EXISTS和IN生成的计划完全相同,这是因为EXISTS比IN更灵活。一个IN始终可以重写为EXISTS(使用带有等联接的简单WHERE条件) ),反之亦然。”
米卡埃尔费利克斯·

3

每个数据库的实现,但您可能会猜到它们都以差不多相同的方式解决了常见问题。如果您使用的是MSSQL,请查看生成的执行计划。您可以通过打开分析器和执行计划来执行此操作。运行命令时,这将为您提供文本版本。

我不确定您使用的是哪个版本的MSSQL,但是可以在查询分析器中的SQL Server 2000中获得图形化版本。我确信此功能潜伏在更高版本的SQL Server Studio Manager中。

看一下行刑计划。除非表很小,否则应尽可能避免表扫描,在这种情况下,表扫描比使用索引快。阅读每个不同方案所产生的不同联接操作。


1

优化器应该足够聪明,可以为常规查询提供两种方式的相同结果。检查执行计划,他们应该给您同样的东西。如果他们不这样做,我通常会认为JOIN更快。但是,所有系统都是不同的,因此您应该对系统上的代码进行概要分析以确保。


5
应该做?也许。可以?不,请参阅我的帖子。
cletus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.