对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。