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

             Summary: Planner adds a hash exchange that re-partitions a join 
input on its existing partitioning (TPC-DS q78)
                 Key: IMPALA-15521
                 URL: https://issues.apache.org/jira/browse/IMPALA-15521
             Project: IMPALA
          Issue Type: Improvement
          Components: Frontend
            Reporter: Zoltán Borók-Nagy


In TPC-DS q78 (master 1f34ea915e, default options), join 18 joins two 
aggregations that are already hash-partitioned compatibly with the join keys:

{noformat}
F03:PLAN FRAGMENT [HASH(d_year,ws_item_sk,ws_bill_customer_sk)]
18:HASH JOIN [RIGHT OUTER JOIN, PARTITIONED]
|  hash predicates: d_year = d_year, ws_bill_customer_sk = ss_customer_sk, 
ws_item_sk = ss_item_sk
|--29:EXCHANGE [HASH(d_year,ss_item_sk,ss_customer_sk)]
|  F07:PLAN FRAGMENT [HASH(d_year,ss_item_sk,ss_customer_sk)]
|  28:AGGREGATE [FINALIZE]
{noformat}

Exchange 29 re-hashes F07's 48.41M rows on exactly the partition exprs F07 
already has. With the query-wide hash seed, every sender instance sends all of 
its rows to one receiver.

*Why:* DistributedPlanner.isCompatPartition() (DistributedPlanner.java:842) 
does not accept this join.
* Condition 2 compares join exprs with partition exprs using List.equals. It 
fails because the join conjuncts are in a different order (year, customer, 
item) than the partition exprs (year, item, customer).
* Condition 3 needs value transfer in both directions, which an outer join does 
not have.

The fallback (:536-546) then uses getCompatPartition() to build an rhs 
partition that matches the lhs. That partition is identical to F07's existing 
one, and an exchange is added on top. The TODO at :506 already mentions 
relaxing the check.

*Impact:* the 1:1 exchange has one channel per sender and is bound by round 
trips.
* MT_DOP=0: q78 takes 27.9 s on master and 12.4 s with the exchange removed.
* MT_DOP=8: it is still about 2 s of q78's 7.6 s.

*Proposed fix* (prototyped; results matched master for all 104 queries):
# Do not add a hash exchange on a join input whose data partition is identical 
to the one the exchange would produce: same exprs, same order, same types. 
Merge the input into the join's fragment instead. Only do this when the 
partition exprs do not reference a tuple that is nullable at the input's root. 
This rule alone removes exchange 29.
# In isCompatPartition(), accept permutations. Each partition position i must 
match one join conjunct j on both sides (lhsPart[i] = lhsJoin[j] and rhsPart[i] 
= rhsJoin[j]), with identical types. Do not apply this to joins that return 
unmatched build rows (RIGHT OUTER, FULL OUTER, RIGHT ANTI).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to