Semi-join在Greenplum中的三种实现方式
Semi-join(半连接)是用来处理外表的记录是否在内表中存在与其匹配的行,而无需考虑匹配行的条数,半连接的返回结果集仅使用外表数据集,使用场景如:in、exists、>|<|= any等操作。本文将为大家详细介绍Semi-join在Greenplum中的三种实现方式。
Semi-Join算子
Semi-join有nestloop semi-join、hash semi-join以及merge semi-join三种形式。外表每行数据在内表中进行探测,只要在内表中找到满足条件的记录,外表数据返回,继续处理外表中下一条数据,无需扫描内表中其余数据,以nestloop semi-join为例,如果第一行数据就符合条件,那么内表其他数据都不需要再扫描,普通nestloop算子每条外表数据都需要对内表做一次全表扫描。Semi-join内外表位置固定,受语义影响,不能交换位置。
建表并插入数据:
create table t1(tc1 int);
create table t2(tc1 int);
insert into t1 select generate_series(1,6);
insert into t2 select generate_series(3,10);
通过调整enable_hashjoin、enable_nestloop、enable_mergejoin三个参数的值构造semi join的三种情况。
Semi-join算子的优点:实现简单,不需要增加额外算子。
Semi-join算子的缺点:Semi-join中内外表位置受语义限制,无法交换,但是join中有些场景小表做内表性能更佳,如hashjoin(小表做内表可以尽量避免使用外存)和nestloop(小表做内表可以将内表数据物化,不需要每次重复扫描)。
Inner Join(外表,unique(内表))
如果内表连接键数据没有重复,那么semi-join可以转换为inner join,因此可以将内表数据先去重,去重后的内表与外表进行inner join连接,实现semi-join的功能,inner join内外表可以交换,从而选择较优计划。
create table t3(tc1 int,tc2 int);
create table t4(tc1 int, tc2 int);
insert into t3 values( generate_series(1,100) ,generate_series(1,1000));
insert into t4 values( generate_series(1,100) ,generate_series(1,100));
执行10次”insert into t4 select * from t4;”向t4中插入重复数据。
analyze t3;
analyze t4;
去重后t4表数据量较小,被选择为内表:
Delete from t3;
Delete from t4;
insert into t3 values( generate_series(1,10) ,generate_series(1,10));
insert into t4 values( generate_series(1,100) ,generate_series(1,100));
执行10次”insert into t4 select * from t4;”向t4中插入重复数据。
analyze t3;
analyze t4;
去重后的t4表数据量较大,做外表,小表t3做内表。
Unique(inner join(外表,内表))
以上两种方式在postgres单库中已经够用,而在MPP数据库中除了考虑连接顺序还需要考虑数据在节点间的分布,上述两种方式只能支持内、外表都按照连接键进行hash分布,或者外表是分布式表,内表复制的场景。无法支持外表复制而内表分布式的场景。
如果两个表t5和t6都是随机分布,外表t5数据量很小,而内表t6数据量很大。为实现semi-join,一种方式是两边均按照连接键重hash,一种是将t6广播,这两种数据转发的代价都相当大,若是inner join,可以采用广播t5的方式,但semi-join若是广播外表按照上述两种实现方式会得到错误结果,外表数据有重复。
因此MPP新增一种semi-join的实现方式,将外表数据进行广播,并对每条外表数据增加rowidexpr列,进行唯一标识,rowidexpr为int64的数据类型,为防止不同节点内产生相同的唯一标识,以节点编号segmentid作为该值的高16位,广播数据后,先做inner join然后对join后的结果按照rowidexpr列去重。
create table t5(tc1 int) distributed randomly;
create table t6(tc1 int) distributed randomly;
insert into t5 select generate_series(1,10);
insert into t6 select generate_series(1,1000000);
analyze t5;
analyze t6;
以上就是semi-join在Greenplum中的三种实现方式,不同的方式适用于不同场景,需要根据代价pk选择出较优计划。
作者简介
赵雪静,Greenplum内核研发
2011年硕士毕业于大连海事大学,之后一直从事国产分布式数据库内核的研发工作。2021年3月加入Greenplum团队,并参与Greenplum内核研发工作。
来一波 “在看”、“分享”和 “赞” 吧!
本文分享自微信公众号 - Greenplum中文社区(GreenplumCommunity)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
macOS Monterey “内存泄露”,控制中心要背锅?
最近升级到macOS Monterey 的部分用户反馈称遇到了“内存泄露”的问题。具体情况是,特定的 macOS 进程或应用程序会在后台长时间保持运行,并消耗异常多的内存。 目前无法确定受影响的具体 Mac 型号是哪些,但从社区和社交媒体上的用户反馈来看,影响范围相对较广,包括最新发布的 14/16 英寸 MacBook Pro 也出现此问题。这些用户表示,他们的 Mac 设备警告系统“已耗尽应用内存”,或是特定的应用程序在 Activity Monitor 中被发现耗费了非常高的内存。 有报道指出 macOS 控制中心是此次“内存泄露”问题的罪魁祸首。YouTube 博主 Gregory McFadden 使用的设备是 64GB 16 英寸 MacBook Pro,搭载M1 Max 处理器。他分享了 macOS 控制中心使用高达 20GB 内存的屏幕截图: 有用户表示使用 Firefox 也出现了类似的情况: 除了这些特定应用消耗大量内存的情况,更多用户的反馈表明,常见问题是弹出"Your system has run out of application memory"的警告——虽...
- 下一篇
Rust 1.56.1 发布,解决 Unicode 安全漏洞问题
Rust 1.56.1 现已发布。此版本引入了两个新的 lints,以减轻最近披露的一个安全问题 CVE-2021-42574的影响: 在 Unicode Specification through 14.0 的双向算法中发现了一个问题。它允许通过控制序列对字符进行视觉重新排序,可用于制作源代码,呈现与编译器和解释器摄取的标记的逻辑顺序不同的逻辑。攻击者可以利用这一点对接受 Unicode 的编译器的源代码进行编码,从而将目标漏洞引入人类审查者不可见的地方。 Rust 官方表示,他们于今年 7 月 25 号收到了报告并开始着手修复。虽然这问题本身不是 rustc 的缺陷,但他们正在采取积极措施来减轻其对 Rust 开发人员的影响。其建议所有用户立即升级,以确保他们的代码库不受该安全问题的影响。 Rust 1.56.1 引入了两个新的 lints,以检测和拒绝包含受影响的 codepoints;而 Rust 1.0.0 到 Rust 1.56.0 中则不包括这样的 lints。公告指出,如果你不对这些 codepoints的存在进行 out-of-band checks,你的源代码就容易...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Hadoop3单机部署,实现最简伪集群
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题