对order by 和limit的处理
对于某些SQL来说,最后需要处理的operator就是order by以及limit。例如下面这个SQL:
select
l_returnflag,
l_linestatus,
sum(l_quantity) as sum_qty,
sum(l_extendedprice) as sum_base_price,
sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
avg(l_quantity) as avg_qty,
avg(l_extendedprice) as avg_price,
avg(l_discount) as avg_disc,
count(*) as count_order
from
lineitem
where
l_shipdate <= date '1998-12-01' - interval '115' day
group by
l_returnflag,
l_linestatus
order by
l_returnflag,
l_linestatus
LIMIT 1;
在PG上生成如下的查询计划:
(limit)
/
/
(order)
/
/
(agg)
/
/
(scan:project and filter = ** )
(注意:请不要纠结最低层的叶子节点scan是否是seq scan 还是index scan)
在mpp的系统中,需要将operator尽量下推以达到最大的并行化。前面已经提到了agg的下推,如何处理剩下的order by和limit是这里需要描述。
对于order by来说,需要分情况处理:如果存在agg并且group by的字段不是sort by的字段,则没有必要下推order by到OP,因为下推这样order by 字段对二次agg没有任何益处,可以直接在DQP上做order by;对于其他情况,可以将order by下推到OP,然后在DQP做多路的merge sort,这个需要修改某些operator(增加一个merge_sort?这会涉及到对PG源码的修改。To Be Done),目前是直接使用了PG中的sort这个operator,可能效率不够高。
对于limit来说,下列情况是不能下推的:如果limit的child node是一个agg,那么只能二次聚集算出agg之后,DQP才能计算limit。