散列连接和合并连接 (Oracle RDBMS) 有啥区别?

Posted

技术标签:

【中文标题】散列连接和合并连接 (Oracle RDBMS) 有啥区别?【英文标题】:What is the difference between a hash join and a merge join (Oracle RDBMS )?散列连接和合并连接 (Oracle RDBMS) 有什么区别? 【发布时间】:2010-11-09 20:21:54 【问题描述】:

哈希联接和合并联接之间的性能增益/损失是什么,特别是在 Oracle RDBMS 中?

【问题讨论】:

download.oracle.com/docs/cd/B28359_01/server.111/b28274/… orafaq.com/node/1446 use-the-index-luke.com/sql/join 【参考方案1】:

“排序合并”连接是通过根据连接键对要连接的两个数据集进行排序,然后将它们合并在一起来执行的。合并非常便宜,但排序可能非常昂贵,特别是如果排序溢出到磁盘。如果可以通过索引按排序顺序访问其中一个数据集,则可以降低排序的成本,尽管与全表扫描相比,通过索引扫描访问表的大部分块也可能非常昂贵.

哈希连接是通过根据连接列将一个数据集散列到内存中并读取另一个数据集并探测哈希表中的匹配项来执行的。当哈希表可以完全保存在内存中时,哈希连接的成本非常低,总成本仅比读取数据集的成本多一点。如果哈希表必须在一次排序中溢出到磁盘,则成本会增加,而对于多次排序,成本会大大增加。

(在 10g 之前的版本中,从大表到小表的外连接在性能方面存在问题,因为优化器无法解决首先访问较小表以进行散列连接的需要,但需要先访问较大表以进行散列连接外连接。因此在这种情况下哈希连接不可用)。

可以通过在连接键上对两个表进行分区来降低哈希连接的成本。这允许优化器推断来自一个表中一个分区的行只会在另一个表的特定分区中找到匹配项,并且对于具有 n 个分区的表,哈希连接作为 n 个独立的哈希连接执行。这具有以下效果:

    减少了每个哈希表的大小,从而减少了所需的最大内存量,并可能消除了操作需要临时磁盘空间的需要。 对于并行查询操作,进程间消息传递的数量大大减少,从而降低了 CPU 使用率并提高了性能,因为每个哈希连接都可以由一对 PQ 进程执行。 对于非并行查询操作,内存需求减少了 n 倍,并且第一行是从更早的查询中预测出来的。

您应该注意,哈希连接只能用于等连接,但合并连接更灵活。

一般来说,如果您在等值连接中连接大量数据,那么哈希连接将是更好的选择。

文档中很好地涵盖了这个主题。

http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/optimops.htm#i51523

12.1 文档:https://docs.oracle.com/database/121/TGSQL/tgsql_join.htm

【讨论】:

谢谢。 “散列连接只能用于等连接,但合并连接更灵活。” Database System Concepts 说两者都只用于等连接和自然连接。 “ 合并连接算法(也称为排序合并连接算法)可用于计算自然连接和等连接。”见***.com/questions/50987379/… @Tim 是的,对于 PostgreSQL 来说很可能是这样,但对于 Oracle 来说不是。 “当满足以下任一条件时,优化器可能会选择排序合并连接而不是哈希连接来连接大量数据:......两个表之间的连接条件不是等值连接,即使用不等式条件,例如如 或 >= ... 与排序合并相比,哈希连接需要相等条件。" docs.oracle.com/database/121/TGSQL/…【参考方案2】:

我只是想为后代编辑这个,因为我回答这个问题时没有添加 oracle 的标签。我的回答更适用于 MS SQL。

Merge join 是最好的,因为它利用了排序,导致单次向下传递表来执行连接。如果您有两个排序相同的表(或覆盖索引),例如主键和该键上表的索引,那么如果您执行该操作,则会产生合并连接。

哈希连接是次优的,因为它通常在一个表具有少量(相对)项目时完成,它有效地创建一个临时表,其中包含每一行的哈希值,然后连续搜索以创建连接。

最坏的情况是嵌套循环,它是 order (n * m),这意味着没有可利用的顺序或大小,连接很简单,对于表 x 中的每一行,搜索表 y 以进行连接。

【讨论】:

如果一个总是比另一个更好,那么另一个永远不会被使用,你不觉得吗?我认为差异比这更复杂。 如果您误解了我,我很抱歉。我试图描述连接的类型以及为什么合并连接是最好的。问题是合并连接仅在您有可利用的排序顺序时才有效,而哈希连接仅在连接表中的行数相对较少时才更有效。如果答案中不清楚,请道歉。 嵌套循环当然是最糟糕的,当没有别的办法时。 嵌套循环并不总是最糟糕的,因为嵌套循环连接返回它们的第一个结果非常快(低延迟)。当您使用提示 first_rows 时,将使用嵌套循环连接的机会很高,因为提示表明您想要低延迟。有时用户更喜欢高吞吐量(例如批处理),有时用户更喜欢低延迟(例如在交互式 UI 中)。 开销也有影响。嵌套循环对于小型数据集表现良好,因为没有开销,只是每行成本。散列连接可能具有快速的每行成本,但构建散列表存在前期开销。

以上是关于散列连接和合并连接 (Oracle RDBMS) 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

004.Oracle数据库 , 查询多字段连接合并

005.Oracle数据库 , 查询多字段连接合并,并添加文本内容

一条sql,有分页,表合并查询,多表连接,用于oracle数据库

加入类型的 Netezza

崔华:Oracle 里的哈希连接原理解析

SQLite中怎么将两个字段字符串合并连接为一个