Join的处理
Join的处理在数据库中占有相当重要的地位。一般来说,在查询优化阶段,PGSQL会首先调用reduce_outer_joins函数来尽量消灭外连接:例如将全外连接转成左、右外连接(或者反左右连接)甚至是内连接,将左右外连接转化成内连接;接着PG会使用动态规划算法来选择一条cost最小的path来确定执行join的先后顺序。
而对于一个分布式的mpp系统来说,join的处理首先和数据的分布有着极大的关系,如果连接的字段就是数据划分的字段,那么可以直接下推join到各个OP执行,如果不是,那么需要选择一种代价比较小的方式:一,将一个小的表做重分布;二,如果表足够小,直接全复制到各个OP。
在TPCH的模型中,我们将fact表根据外键进行了水平分片,对dimension表进行全复制,而涉及到fact表的Join的SQL中,fact表都通过划分字段来进行关联的。因此无需进行重分布。
例如,对于TPCH的模板14生成的SQL实例来说:
select 100.00 * sum(case when p_type like 'PROMO%' then l_extendedprice * (1 - l_discount) else 0 end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenuefrom lineitem, partwhere l_partkey = p_partkey and l_shipdate >= date '1995-11-01' and l_shipdate < date '1995-11-01' + interval '1' monthLIMIT 1;
ppg_planner会将如下的SQL通过foreign_scan 推给OP,在DQP上只执行100*sum(a1)/sum(a2)和limit:
select sum(case when p_type like 'PROMO%' then l_extendedprice * (1 - l_discount) else 0 end) as a1, sum(l_extendedprice * (1 - l_discount)) as a2from lineitem, partwhere l_partkey = p_partkey and l_shipdate >= date '1995-11-01' and l_shipdate < date '1995-11-01' + interval '1' month