PostgreSQL/GreenPlum Merge Inner Join解密

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: PostgreSQL/GreenPlum Merge Inner Join解密

PostgreSQL/GreenPlum Merge Inner Join解密

1、什么是Merge Join


合并连接是一种匹配算法,其中外表的每个记录与内表的每个记录进行匹配,直到存在连接子句匹配的可能性为止。仅当两个表都已排序并且join子句的运算符是“=”时,才使用该算法。

如下图所示:merge join的字节点需要Sort节点对内外表进行排序,然后进行join。

2、Merge Inner Join状态机


状态机如下图所示:

EXEC_MJ_INITIALIZE_OUTER


该状态是初始状态,首先要从外表进行扫描。获取外表记录。根据外表扫描的记录进行判断:

1)外表为空,即扫描出来的记录为空,或者第一个join条件的左表值为NULL并且null排序后放在最后且为inner join,则结束join,返回NULL

2)左表值为NULL或者null排序后放在前面,则重新进入EXEC_MJ_INITIALIZE_OUTER状态,扫描左表

3)非上述两种条件,则进入EXEC_MJ_INITIALIZE_INNER状态,获取内表记录


EXEC_MJ_INITIALIZE_INNER


该状态下扫描内表。根据扫描的记录进行判断:

1)内表为空,即扫描出来的记录为空,或者第一个join条件的左表值为NULL并且null排序后放在最后且为inner join,则结束join,返回NULL

2)内表值为NULL或者null排序后放在前面,则重新进入EXEC_MJ_INITIALIZE_INNER状态,扫描右表

3)非上述两种条件,则进入EXEC_MJ_SKIP_TEST状态


EXEC_MJ_SKIP_TEST


该状态需要对左右表值进行join条件比较,根据比较结果判断:

1)= 右:标记内表排序后当前扫描位置;标记当前扫描的slot,进入EXEC_MJ_JOINTUPLES状态

2)< 右:进入EXEC_MJ_SKIPOUTER_ADVANCE状态,扫描左表下一条记录

3)> 右:进入EXEC_MJ_SKIPINNER_ADVANCE状态,扫描右表下一条记录


EXEC_MJ_SKIPOUTER_ADVANCE


该状态扫描外表下一条记录。根据扫描的记录进行判断:

1)外表扫描完,即扫描出来的记录为空,或者第一个join条件的左表值为NULL并且null排序后放在最后且为inner join,则结束join,返回NULL

2)左表值为NULL或者null排序后放在前面,则重新进入EXEC_MJ_SKIPOUTER_ADVANCE状态,扫描左表

3)非上述两种条件,则进入EXEC_MJ_SKIP_TEST状态,进行比较


EXEC_MJ_SKIPINNER_ADVANCE


该状态扫描内表下一条记录,根据扫描的记录进行判断:

1)内表扫描完,即扫描出来的记录为空,或者第一个join条件的左表值为NULL并且null排序后放在最后且为inner join,则结束join,返回NULL

2)内表值为NULL或者null排序后放在前面,则重新进入EXEC_MJ_SKIPINNER_ADVANCE状态,扫描内表

3)非上述两种条件,则进入EXEC_MJ_SKIP_TEST状态,进行比较

因为左> 右才会进入该状态,右时一个NULL,那么左表后面的值肯定也比右的前一个值大,所以join结束。


EXEC_MJ_JOINTUPLES


该状态下,将左右表的值进行连接投影,输出结果。下个周期调用ExecMergeJoin函数时,直接进入EXEC_MJ_NEXTINNER状态。


EXEC_MJ_NEXTINNER


该状态下,扫描内表下一条记录。并根据扫描的记录进行判断:

1)内表扫描完,即扫描出来的记录为空,或者第一个join条件的左表值为NULL并且null排序后放在最后且为inner join,则进入EXEC_MJ_NEXTOUTER状态

2)内表值为NULL或者null排序后放在前面,则进入EXEC_MJ_NEXTOUTER状态

3)非上述两种条件,进行比较,根据比较值进行操作:

= 右:进入EXEC_MJ_JOINTUPLES状态

< 右:进入EXEC_MJ_NEXTOUTER状态

不可能有左> 右的分支,因为该状态由分支而来,排序都是由小到大,所以要么相等,要么右边大


EXEC_MJ_NEXTOUTER


该状态下获取外表的下一条记录,并根据值进行判断:

1)外表扫描完,即扫描出来的记录为空,或者第一个join条件的左表值为NULL并且null排序后放在最后且为inner join,则结束join,返回NULL

2)左表值为NULL或者null排序后放在前面,则重新进入EXEC_MJ_NEXTOUTER状态,获取外表下一条记录

3)非上述两种条件,则进入EXEC_MJ_JOINTUPLES状态,否则进入EXEC_MJ_TESTOUTER状态


EXEC_MJ_TESTOUTER


该状态下,获取标记的内表值,并与外表值比较

1)= 右:需要标记内表排序的位置,并将当前slot放到mj_InnerTupleSlot中

2)> 右:重新获取右表当前扫描的位置的记录

(1)内表扫描完,或者内表记录为NULL并且第一个join条件并且null排在最后,结束join,返回NULL

(2)内表记录为NULL,并且非第一个join条件或null排在前面,进入EXEC_MJ_SKIPINNER_ADVANCE状态,获取内表下一条记录

(3)非上述2种情况,进入EXEC_MJ_SKIP_TEST状态

不可能有左< 右的分支,因为该状态由而来,排序都是由小到大,要么相等,要么左边大。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
存储 监控 OLAP
【ClickHouse 技术系列】- 在 ClickHouse 物化视图中使用 Join
本文翻译自 Altinity 针对 ClickHouse 的系列技术文章。面向联机分析处理(OLAP)的开源分析引擎 ClickHouse,因其优良的查询性能,PB级的数据规模,简单的架构,被国内外公司广泛采用。本系列技术文章,将详细展开介绍 ClickHouse。
【ClickHouse 技术系列】- 在 ClickHouse 物化视图中使用 Join
|
10月前
|
存储 算法 关系型数据库
PostgreSQL的B-tree索引(上)
PostgreSQL的B-tree索引
90 0
|
10月前
|
存储 SQL 关系型数据库
PostgreSQL的B-tree索引(下)
PostgreSQL的B-tree索引(下)
94 0
|
SQL 关系型数据库 PostgreSQL
PostgreSQL连接(JOIN)
PostgreSQL JOIN子句用于把两个或多个表的行结合起来,基于这些表之间的共同变量。 在PostgreSQL中,JOIN有五种连接类型: CROSS JOIN:交叉连接 内连接:内连接 LEFT OUTER JOIN:左外连接 右外连接:右外连接 FULL OUTER JOIN:全外连接 接下来让我们创建两张表COMPANY和DEPARTMENT。
460 0
|
SQL 分布式计算 并行计算
PostgreSQL 并行计算解说 之18 - parallel merge join
标签 PostgreSQL , cpu 并行 , smp 并行 , 并行计算 , gpu 并行 , 并行过程支持 背景 PostgreSQL 11 优化器已经支持了非常多场合的并行。简单估计,已支持27余种场景的并行计算。 parallel seq scan
844 0
|
SQL 关系型数据库
PostgreSQL citus, Greenplum 分布式执行计划 DEBUG
标签 PostgreSQL , citus , sharding , Greenplum , explain , debug 背景 开启DEBUG,可以观察citus, Greenplum的SQL分布式执行计划,下发情况,主节点,数据节点交互情况。
1599 0
|
关系型数据库 PostgreSQL
PostgreSQL sharding : citus 系列6 - count(distinct xx) 加速 (use 估值插件 hll|hyperloglog)
标签 PostgreSQL , hll , hyperloglog , distinct , 加速 , citus.count_distinct_error_rate 背景 在分布式数据库中,计算count(distinct xxx),需要对distinct 的字段, 1、去重, 2、重分布去重后的数据,(这一步,如果distinct值特别多,那么就会比较耗时) 3、然后再去重, 4、最后count (xxx), 5、求所有节点的count SUM。
1787 0
|
关系型数据库 PostgreSQL