2.1 嵌套连接(nested loop)
对左边的关系里面找到的每条行都对右边关系进行一次扫描。这个策略容易实现,但是可能会很耗费时间。但是,如果右边的关系可以用索引扫描,那么这个可能就是个好策略。可以用来自左边关系的当前行的数值为键字进行对右边关系的索引扫描。
一般用在连接的表中有索引,并且索引选择性较好的时候;而在没有索引的情况下,嵌套连接的代价通常会很大。
eg:
create table tb1(a int,b int);create table tb2(a int,b int); explain (costs off) select * from tb2,tb1 where tb2.a > tb1.a; QUERY PLAN ---------------------------------------- Streaming (type: GATHER) Node/s: All datanodes -> Nested Loop Join Filter: (tb2.a > tb1.a) -> Streaming(type: BROADCAST) Spawn on: All datanodes -> Seq Scan on tb2 -> Materialize -> Seq Scan on tb1 (9 rows)
2.2 归并/排序连接(merge join)
在连接开始之前,每个关系都对连接字段进行排序。然后对两个关系并发扫描,匹配的行就组合起来形成连接行。这种联合更有吸引力,因为每个关系都只用扫描一次。要求的排序步骤可以通过明确的排序步骤,或者是使用连接键字上的索引按照恰当的顺序扫描关系。
eg: explain (costs off) select * from tb2,tb1 where tb2.a = tb1.a; Streaming (type: GATHER) Node/s: All datanodes -> Merge Join Merge Cond: (tb2.a = tb1.a) -> Sort Sort Key: tb2.a -> Seq Scan on tb2 -> Sort Sort Key: tb1.a -> Seq Scan on tb1 (10 rows)
归并连接的效率很高,只要时间复杂度是约是O(n)+O(m)的数量级,n,m是参与连接表的长度。但也有极端的情况,比如该列只有一个取值,那么每一条记录都是可连接的,则退变为嵌套连接,为O(n2)的复杂度。
另外,归并连接需要参与连接的两表都是排序好的,若表本身是无序的,那么对表本身进行排序也需要相应的开销。所以,最好是排序字段有索引,可以藉由索引获取有序表。不过话说回来,既然有索引,那么本身嵌套连接也是个不错的选择了。
2.3 哈希连接(hash join)
首先扫描右边的关系,并用连接的字段作为散列键字加载进入一个 Hash 表,然后扫描左边的关系,并将找到的每行用作散列键字来以定位表里匹配的行。
哈希连接通常使用在处理大数据集的场合,并且两表的数据量差别较大。
eg:
explain (costs off) select * from tb1, tb2 where tb1.a = tb2.a; QUERY PLAN ------------------------------------ Streaming (type: GATHER) Node/s: All datanodes -> Hash Join Hash Cond: (tb1.a = tb2.a) -> Seq Scan on tb1 -> Hash -> Seq Scan on tb2 (7 rows)
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。