房地产集团网站欣赏,建设网站最重要的是什么,维度网络做网站,网页设计代码基础模板GPDB技术内幕 - SEMI JOIN浅析 SEMI JOIN顾名思义#xff0c;半连接#xff0c;相对于join字段来说#xff0c;针对外表的一行记录#xff0c;内表只要有一条满足#xff0c;就输出外表记录。注意#xff0c;这里是仅输出外表记录。GPDB中有几种实现方式#xff0c;本文… GPDB技术内幕 - SEMI JOIN浅析 SEMI JOIN顾名思义半连接相对于join字段来说针对外表的一行记录内表只要有一条满足就输出外表记录。注意这里是仅输出外表记录。GPDB中有几种实现方式本文我们简单聊聊。 从代码中我们看到SEMI JOIN的类型有3类 1、JOIN_SEMI 这是普通实现方式。针对nestloop join、merge join、hash join的inner join来说只要针对JOIN字段内表有记录就输出外表记录。以nestloop join为例 外表和内表记录是无序的针对外表第一个记录1遍历内表。内表第一记录为11不匹配继续下一条记录下一条是1join匹配输出外表1的值此时针对外表记录1就不必继续内表扫描了join结束继续外表下一个记录10重新扫描内表进行join条件判断。 这种方式是通用实现方式。下面看第二种实现方式。 2、JOIN_UNIQUE_OUTER/JOIN_UNIQUE_INNER 从SEMI JOIN的语义中可以看出join过成中外表一个值仅能匹配内表一个值这样我们就可以先将内表进行去重然后再进行普通inner join从而实现SEMI JOIN。 先将内表进行去重可以通过group by进行聚合hash agg或者sort agg去重得到内表值然后针对外表1顺序扫描内表去重后的值11不匹配继续下一个值下一个值是1匹配输出外表值1。针对Join的结果内表因为去过重所以满足join条件的必然只有一个值。 3、JOIN_DEDUP_SEMI/JOIN_DEDUP_SEMI_REVERSE 以上两种实现方式是沿用PgSQL针对的是集中式实现方式。GPDB是分布式当分布键不匹配时就需要进行广播MOTION即使每个segment上去过重广播MOTION后仍旧可能存在重复值这样就不能使用第2种实现方式。比如下面案例第三种实现方式 postgres# explain select * from s where exists (select 1 from r where s.a r.b);QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost153.50..155.83 rows100 width8)
- HashAggregate (cost153.50..153.83 rows34 width8)Group Key: (RowIdExpr)- Redistribute Motion 3:3 (slice2; segments: 3) (cost11.75..153.00 rows34 width8)Hash Key: (RowIdExpr)- Hash Join (cost11.75..151.00 rows34 width8)Hash Cond: (r.b s.a)- Seq Scan on r (cost0.00..112.00 rows3334 width4)- Hash (cost8.00..8.00 rows100 width8)- Broadcast Motion 3:3 (slice3; segments: 3) (cost0.00..8.00 rows100 width8)- Seq Scan on s (cost0.00..4.00 rows34 width8)
Optimizer: Postgres query optimizer
(12 rows) 分析 1上面案例s作为内表r作为外表。s表远大于r表。s广播motion记录数量众多代价非常大 2Hash join构建hash表阶段进行去重 3外表r不可以广播motion否则会产生重复值 4基于上述原因只能选择广播大表进行JOIN_SEMI了 所以GPDB实现了第3种方式即先进行join然后再去重。主要是为了能够广播小表比如上述例子种的小表r作为外表即使产生重复值也可以在去重阶段去掉。 为了方便去重GPDB引入了表达式RowIdExpr即去重操作DISTINCT ON (RowIdExpr)。该表达式为一条记录产生唯一标识值附加到该记录中作为一个额外字段。广播后进行join相对于JOIN_SEMI计划多了一个重分布MOTION节点当然MOTION的记录都非常少。上述例子中可以看到hash join后需要在RowIdExpr上进行重分布然后再在RowIdExpr这个字段上通过Hash Agg进行去重。鉴于hash join前的广播分布和join后的重分布传输的记录数量都比较小JOIN_DEDUP_SEMI实现方式就在三种实现方式中胜出了。