散列联接和合并联接(特别是在Oracle RDBMS中)之间的性能增益/损失是什么?
发布于 2009-07-11 17:58:55
“排序合并”连接是通过根据连接键对要连接的两个数据集进行排序,然后将它们合并在一起来执行的。合并非常便宜,但排序可能非常昂贵,特别是当排序溢出到磁盘时。尽管与全表扫描相比,通过索引扫描访问表的高比例块也可能是非常昂贵的,但是如果可以通过索引按排序顺序访问数据集之一,则可以降低排序的成本。
散列连接是通过基于连接列将一个数据集散列到内存中,并读取另一个数据集并探测散列表中的匹配项来执行的。当哈希表可以完全保存在内存中时,哈希连接的成本非常低,总成本比读取数据集的成本高出很少。如果哈希表必须以一遍排序的方式溢出到磁盘,那么成本就会增加,而对于多遍排序,成本就会大大增加。
(在10g之前的版本中,从大表到小表的外部连接在性能方面是有问题的,因为优化器不能解决首先访问较小表以进行散列连接的需要,而需要先访问较大表以进行外部连接。因此,哈希连接在这种情况下不可用)。
通过对连接键上的两个表进行分区,可以降低散列连接的成本。这允许优化器推断来自一个表中的分区的行将仅在另一个表的特定分区中找到匹配,并且对于具有n个分区的表,散列联接作为n个独立的散列联接来执行。这会产生以下影响:
您应该注意到,哈希连接只能用于等连接,但合并连接更灵活。
一般而言,如果您要在equi-join中连接大量数据,那么哈希连接将是更好的选择。
文档中对此主题进行了很好的介绍。
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
发布于 2009-07-11 12:11:19
我只想为后人编辑这篇文章,因为我回答这个问题时没有添加oracle的标签。我的回答更适用于MS SQL。
合并连接可能是最好的,因为它利用了排序,导致单次向下传递表来执行连接。如果您有两个具有相同顺序的表(或覆盖索引),例如主键和该键上的表的索引,那么如果您执行该操作,将会产生合并联接。
散列连接是第二好的,因为它通常在一个表具有少量(相对)项时完成,它有效地创建了一个临时表,其中包含每一行的散列,然后不断搜索该表以创建连接。
最坏的情况是嵌套循环,它是order (n * m),这意味着没有排序或大小可供利用,而连接只是针对表x中的每一行在表y中搜索要执行的连接。
https://stackoverflow.com/questions/1111707
复制相似问题