【问题标题】:Use A Union Or A Join - What Is Faster [closed]使用联合或连接 - 更快[关闭]
【发布时间】:2010-02-22 09:31:50
【问题描述】:

我只是想知道你是否有一个表并且你联合它会比使用连接更有效吗??

我确实知道连接会创建更多列,但这更具理论性 - 联合是否需要像连接一样对另一个表进行嵌套循环扫描?

【问题讨论】:

  • 在这个问题和/或答案有一些具体的例子之前,我投票结束,因为太误导了。
  • 如果 Union/Union All 简单地连接组,它们是否不再按排序顺序排列?因此,更远的操作(比如联合在子查询或 CTE 中)是否会遇到性能问题?连接应该产生一个排序的或者至少是哈希映射的输出。
  • "Unioned it" & "using a join" 没有任何意义。加入和联合是不同的运算符。他们返回不同的东西。您想完成什么可以通过其中一个以及其他运算符表达

标签: sql mysql


【解决方案1】:

Union 会更快,因为它只是传递第一个 SELECT 语句,然后解析第二个 SELECT 语句并将结果添加到输出表的末尾。

Join 将遍历两个表的每一行,在另一个表中查找匹配项,因此需要更多处理,因为要为每一行搜索匹配的行。

编辑

Union 是指 Union All,因为它似乎足以满足您想要实现的目标。虽然普通的 Union 通常比 Join 更快。

编辑 2(回复@seebiscuit 的评论)

我不同意他的观点。从技术上讲,无论您的联接有多好,“联接”仍然比纯串联更昂贵。我在我的博客codePERF[dot]net 上发表了一篇博文来证明这一点。实际上,它们有两个完全不同的目的,更重要的是确保您的索引是正确的并使用正确的工具来完成这项工作。

从技术上讲,我认为可以使用我的博客文章中的以下 2 个执行计划来总结:

UNION ALL执行计划

JOIN执行计划

实际结果

实际上,聚集索引查找的差异可以忽略不计:

【讨论】:

  • 您所描述的不是UNION,而是UNION ALL。 UNION 必须匹配结果之间的记录才能删除重复项。这可能比加入的成本更高。
  • 即使在删除重复项时,它所要做的只是在另一个表上传递一遍,而不是将每一行添加到输出表中,它会简单地检查它是否已经存在。是的,在某些情况下它可能会更慢。因此海报你应该使用 UNION ALL 从它的声音来看,它对你来说应该足够了。感谢您的来信。
  • 想知道你对@Domas Mituzas 回答的看法,如下。
  • @seebiscuit 查看我对我的 cmets 的编辑。不管是什么喜欢UNION ALL 都会比任何JOIN 更快。但最重要的是,它们是用于 2 种不同工作的 2 种不同工具。
  • 我不赞成这个答案,因为它使UNION 更快的笼统的、不正确的声明。当然,在某些查询中它更快,但不是大多数,当然也不是全部。
【解决方案2】:

JOINUNION 有两个不同的用途。 JOIN 用于向查询添加其他表,以添加选择条件和可能的其他列。 UNION 用于将两个不同查询的结果与相同的列组合在一起。问哪个更有效率,就像问“一条面包”和“吹来的风”哪个更“橙色”。

【讨论】:

  • “一条面包”绝对比“吹来的风”更“橙色”;-)
  • 不一定,它们可以用来实现完全相同的东西。一个带有 ON x OR y inside (SLOW) 的连接或 2 个带有单独连接 X 和连接 Y 的查询联合在一起。结果相同,性能差异很大。
  • 简要说明何时使用JOIN 以及何时使用UNION。反驳论点涉及使一个达到另一个目的的杂耍。
  • 不一定是真的。例如,当使用 JPA 的继承时,在 JOIN 和 UNION 之间进行选择是通过 @Inheritance 注释以声明方式完成的。
【解决方案3】:

很抱歉破坏了你的聚会,但写得好的加入会比工会更快。

  • 它使用更轻量级的统计数据收集模型(基于基数,而不是随机潜水)
  • 查询将被解析一次(不需要多次子选择评估)
  • resultset 不会在 temptable 中具体化(对于 UNION ALL,它甚至会实现)

【讨论】:

  • 我的 union all 查询需要更长的时间,我很困惑。多亏了你的解释,我不用伤脑筋了。
  • JOIN 和“subselect”是两个不同的东西。您的项目符号 #2 不(通常)适用。
【解决方案4】:

单个 SELECT 将使用每个表不超过一个索引。 UNION 将在联合中的每个 SELECT 使用不超过一个索引。

UNION 将更好地利用索引,从而加快查询速度。

【讨论】:

    猜你喜欢
    • 2012-11-11
    • 2015-06-23
    • 2021-09-28
    • 2019-05-14
    • 2016-09-28
    • 2012-11-11
    • 2010-11-09
    • 1970-01-01
    相关资源
    最近更新 更多