Greenplum的Hash Join

Greenplum的Hash Join


在介绍HashJoin实现之前,首先了解下什么是 JOIN。根据维基百科(WIKIPedia),JOIN是关系数据库中组合一个或者多个表中的columns的算子。
在这里插入图片描述
而JOIN 有多种类型, SQL 标准中定义了 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN 等四种类型,用集合论里的操作非常容易理解。 我们在下图直观的解释了这四种JOIN类型的效用。

此外还有其中JOIN类型,譬如 SEMI JOIN和 ANTI JOIN。 这两种JOIN不是 SQL 语法,然而通常用来实现某些 SQL 功能,后面会详细介绍他们。
在这里插入图片描述
本文将使用这样一个例子。 例子里面包含两张表:student表和score表,每张表都有几条记录。
在这里插入图片描述

testdb=# create table student(id int, name text, age int) distributed by(id);
CREATE TABLE
testdb=# insert into student values (10,'Jack',25),(12,'Tom',26),(13,'Ariel',25);
INSERT 0 3
testdb=# create table score(id int, stu_id int, subject text, score int) distributed by(stu_id);
CREATE TABLE
testdb=# insert into score values (1,10,'math',95),(2,10,'history',98),(3,12,'math',97),(4,15,'history',92);
INSERT 0 4

首先我们看下图中JOIN对应的 SQL语句。 通过 explain 可以查看这6个SQL例子的JOIN类型。 (需要设置 enable_mergejoin, enable_hashagg 为 OFF,否则优化器可能会选择其他查询计划)
在这里插入图片描述

testdb=# set enable_mergejoin = off;
SET
testdb=# set enable_hashagg = off;
SET

下图展示了查询结果,让我们对图中JOIN的作用有个直观的认知。
在这里插入图片描述

testdb=# select * from student;
 id | name  | age
----+-------+-----
 10 | Jack  |  25
 12 | Tom   |  26
 13 | Ariel |  25
(3 rows)

testdb=# select * from score;
 id | stu_id | subject | score
----+--------+---------+-------
  4 |     15 | history |    92
  1 |     10 | math    |    95
  2 |     10 | history |    98
  3 |     12 | math    |    97
(4 rows)

testdb=# select name, score from student st inner join score s on st.id = s.stu_id;
 name | score
------+-------
 Jack |    98
 Jack |    95
 Tom  |    97
(3 rows)

testdb=# select name, score from student st left join score s on st.id = s.stu_id;
 name  | score
-------+-------
 Jack  |    98
 Jack  |    95
 Ariel |
 Tom   |    97
(4 rows)

testdb=# select name, score from student st right join score s on st.id = s.stu_id;
 name | score
------+-------
 Tom  |    97
      |    92
 Jack |    95
 Jack |    98
(4 rows)

testdb=# select name, score from student st full join score s on st.id = s.stu_id;
 name  | score
-------+-------
       |    92
 Jack  |    95
 Jack  |    98
 Ariel |
 Tom   |    97
(5 rows)

testdb=# select id, name from student st where exists(select id from score s where st.id = s.stu_id);
 id | name
----+------
 10 | Jack
 12 | Tom
(2 rows)

testdb=# select name from student st where not exists(select stu_id from score s where st.id = s.stu_id);
 name
-------
 Ariel
(1 row)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值