【问题标题】:SQL JOIN vs IN performance?SQL JOIN 与 IN 性能?
【发布时间】:2010-11-15 01:51:52
【问题描述】:

我有一个案例,使用 JOIN 或 IN 会给我正确的结果...通常具有更好的性能,为什么?这在多大程度上取决于您正在运行的数据库服务器? (仅供参考,我使用的是 MSSQL)

【问题讨论】:

  • :) 我实际上是在寻找一篇不同的文章,我在不久前研究类似的东西时使用过,但偶然发现了那篇文章
  • 对不起,可能是骗子...我在搜索时没有找到那个问题
  • 请注意,这个问题直接询问性能差异(取决于优化)。但是,JOIN 和 IN 有不同的语义!由于 SQL 是一种声明性语言,我建议使用适合您的用例的方式,依赖底层查询优化器(尽可能长)。因此,如果可能,首先检查哪种方式更适合(在这种情况下可能是 IN 甚至 EXISTS)。

标签: sql sql-server performance tsql


【解决方案1】:

一般来说,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 中产生相同的计划。

如果不是,那么INDISTINCT 上的JOIN 快。

有关性能详情,请参阅我的博客中的这篇文章:

【讨论】:

  • 是的,如果加入列是唯一的(在我的情况下),它们会执行相同的操作是有道理的
  • 类似地,我应该使用 IN(SELECT DISTINCT ...) 还是简单地使用 IN(SELECT ...)?
  • @orlandu63: IN 暗示 DISTINCTSQL Server 足够聪明,可以注意到它,并且会为两个查询生成相同的计划。不过,不确定其他 RDBMS 的行为会如何。
  • >>IN 和 JOIN 是不同的查询,可以产生不同的结果。你能解释一下为什么在这种情况下即使 b.col 不是唯一的,它也会产生不同的结果吗?
【解决方案2】:

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

作为一般经验法则,我认为如果您的外键列上有索引,并且如果您只(或大部分)使用 INNER JOIN 条件,那么 JOIN 会稍微快一些。

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

马克

【讨论】:

  • 我也是这么想的...因为看起来 JOIN 是一种更常见的情况,并且更有可能被优化
【解决方案3】:

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

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

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

如果 col 没有被索引,差异可能会很大,因为 db 不必找到 b 中与 col 具有相同值的所有记录,它只需要找到第一个。如果 b.col 上没有索引并且 b 中有很多记录,则结果可能是表扫描。使用 IN 或 JOIN 这将是全表扫描,使用 EXISTS 这将只是部分表扫描(直到找到第一个匹配记录)。

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

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

【讨论】:

  • 在 MSSql 上,存在比 IN 更好的事实似乎不正确。更多信息:explainextended.com/2009/06/16/in-vs-join-vs-exists 在这里你可以读到:“很多人认为 EXISTS 比 IN 更有效,因为 EXISTS 只返回一行。这对于 SQL Server 来说不是这样。从上面的例子中我们可以看到,EXISTS和 IN 产生完全相同的计划。这是因为 EXISTS 比 IN 更灵活。IN 总是可以重写为 EXISTS(使用带有等值连接的简单 WHERE 条件),反之则不行。”
【解决方案4】:

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

我很确定,假设关系和索引得到维护,Join 的整体性能会更好(与其他操作相比,使用该操作需要付出更多努力)。如果您从概念上考虑它,那么它就是 2 个查询和 1 个查询之间的区别。

您需要将它连接到查询分析器并尝试一下,看看有什么不同。还要查看查询执行计划并尽量减少步骤。

【讨论】:

    【解决方案5】:

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

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

    查看执行计划。尽可能避免表扫描,除非您的表当然很小,在这种情况下,表扫描比使用索引更快。阅读每个不同场景产生的不同连接操作。

    【讨论】:

      【解决方案6】:

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

      【讨论】:

      • 应该做吗?可能是。可以?不,请参阅我的帖子。
      猜你喜欢
      • 2023-03-17
      • 2011-01-05
      • 2023-04-10
      • 2016-03-16
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多