Zoltán Borók-Nagy created IMPALA-15687:
------------------------------------------

             Summary: Calcite: nested UNION DISTINCTs are not merged into one 
n-ary union (TPC-DS q75: an extra de-duplication and a 0.8B-row shuffle per 
year)
                 Key: IMPALA-15687
                 URL: https://issues.apache.org/jira/browse/IMPALA-15687
             Project: IMPALA
          Issue Type: Improvement
          Components: Frontend
            Reporter: Zoltán Borók-Nagy


With PLANNER=CALCITE, {{A UNION B UNION C}} is planned as two nested unions, 
each with its own de-duplication. TPC-DS q75 unions catalog, store and web 
sales for two years. On master (TPC-DS SF10000, 12 executors, MT_DOP=8, 
PLANNER=CALCITE, best of 3: 62.3 s), the first year runs:
* {{01:UNION}} (catalog, store) -> {{62:EXCHANGE}} (835.69M rows) -> 
{{63:AGGREGATE}} FINALIZE (743.06M rows, 3.37 s avg per instance);
* {{00:UNION}} (63, web) -> {{68:EXCHANGE}} (887.46M rows) -> {{69:AGGREGATE}} 
FINALIZE.

The other year shuffles 820.61M rows into its first de-duplication ({{81}}, 
729.68M rows). The union opens its children one at a time 
({{union-node.cc:232}}), so the web probe ({{23}}) starts only at 53.4-53.9 s, 
after 63 has emitted its rows (from 49.0 s). A flat union does not avoid that 
wait: with the legacy planner the web probe starts at 52.1-53.2 s (q75: 61.2 s, 
best of 3), so merging mainly saves the extra shuffle and de-duplication.

The legacy planner already flattens the chain ({{SetOperationStmt.java:329}} 
propagateDistinct(), {{:340}} unnestOperands()). Its q75 plan has one 
three-operand UNION and one de-duplication per year (compare 
{{tpcds/tpcds-q75.test}} with {{calcite_tpcds/tpcds-q75.test}}). q49 has the 
same nested shape, on small inputs.

*Cause* (master c580d36e61): {{CalciteOptimizer.runExpandNodesProgram()}} 
({{CalciteOptimizer.java:212-221}}) applies {{UNION_TO_DISTINCT}} bottom-up, so 
{{Union(Union(cs, ss), ws)}} becomes 
{{Aggregate(UnionAll(Aggregate(UnionAll(cs, ss)), ws))}}. 
{{ImpalaCoreRules.UNION_MERGE}} ({{ImpalaCoreRules.java:123}}) wraps Calcite's 
UnionMergeRule, which merges a DISTINCT union with a nested union, but no 
program uses it.

*Proposal:*
* Run {{UNION_MERGE}} before {{UNION_TO_DISTINCT}} as a separate step. In the 
same bottom-up collection, the inner union is rewritten first and can no longer 
be merged.
* Consider {{INTERSECT_MERGE}} and {{MINUS_MERGE}} too: the nested INTERSECT of 
q38 and EXCEPT of q87 also get two levels of aggregation.
* Test mixed UNION/INTERSECT chains (IMPALA-13540) and UNION ALL under UNION 
DISTINCT.

The gain has not been measured with a prototype.




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to