You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem or challenge?
In PR #24600 ("Adapt existing partitioning for unsatisfied inputs in co-partitioned joins"), enforce_distribution_relationships was introduced to adapt unsatisfied children in co-partitioned joins to an existing satisfied reference partitioning.
// so the optimizer avoids arbitrary tie-breaking and falls back to
// standard distribution.
candidates
.iter()
.find(|(size_a, idx_a, _)| {
size_a.is_known()
&& candidates.iter().all(|(size_b, idx_b, _)| {
idx_a == idx_b || size_a > size_b
})
})
.map(|(_, idx, part)| (*idx, part.clone()))
}
}
};
Notice the current selection logic:
When satisfied_children.len() > 1: DataFusion inspects PlanSize across the candidate satisfied children and only selects a reference candidate if there is a unique, strictly larger winner (size_a > size_b), avoiding arbitrary tie-breaking:
// so the optimizer avoids arbitrary tie-breaking and falls back to
// standard distribution.
candidates
.iter()
.find(|(size_a, idx_a, _)| {
size_a.is_known()
&& candidates.iter().all(|(size_b, idx_b, _)| {
idx_a == idx_b || size_a > size_b
})
})
.map(|(_, idx, part)| (*idx, part.clone()))
But when satisfied_children.len() == 1: DataFusion unconditionally selects that single satisfied child as the reference partitioning without checking its size relative to the unsatisfied children that will be adapted to it:
The Problem in Asymmetric Joins:
In an asymmetric join where only one table has a declared partition key matching the join condition (for example, a small dimension table with 100 rows is range-partitioned, but a large fact table with 100M rows is unpartitioned on that join key):
satisfied_children contains only the small dimension table (len == 1).
DataFusion chooses the 100-row dimension table as the reference child.
The 100M-row fact table is forced to repartition (via ref_partitioning.adapt(...)) to match the small table's partition boundaries.
In distributed environments, this causes the 100M-row table to be shuffled across the network to match the 100-row table, rather than keeping the large table local and shuffling the small table (or falling back to symmetric hash partitioning / broadcast).
Describe the solution you'd like
When satisfied_children.len() == 1 (or before selecting any reference child), compare the PlanSize of the candidate satisfied reference child against the PlanSize of the unsatisfied children that would be adapted to it.
If an unsatisfied child is strictly larger than the satisfied reference child (unsatisfied_size > reference_size):
Do not select the smaller child as the reference.
Return None for best_satisfied_child so that the join falls back to standard symmetric distribution (e.g. symmetric hash repartitioning or broadcast), preventing an asymmetric 1-sided shuffle of the larger relation.
Describe alternatives you've considered
Downstream query planners currently have to defend against this by artificially withholding / refusing to stamp partition metadata on smaller tables in asymmetric joins to prevent DataFusion from shuffling the larger partner to match the smaller table.
Having DataFusion check PlanSize before adapting larger unsatisfied children to a smaller satisfied child would make enforce_distribution_relationships robust against asymmetric joins out of the box.
Is your feature request related to a problem or challenge?
In PR #24600 ("Adapt existing partitioning for unsatisfied inputs in co-partitioned joins"),
enforce_distribution_relationshipswas introduced to adapt unsatisfied children in co-partitioned joins to an existing satisfied reference partitioning.When selecting
best_satisfied_child:datafusion/datafusion/physical-optimizer/src/ensure_requirements/enforce_distribution.rs
Lines 1181 to 1229 in f40d978
Notice the current selection logic:
satisfied_children.len() > 1: DataFusion inspectsPlanSizeacross the candidate satisfied children and only selects a reference candidate if there is a unique, strictly larger winner (size_a > size_b), avoiding arbitrary tie-breaking:datafusion/datafusion/physical-optimizer/src/ensure_requirements/enforce_distribution.rs
Lines 1213 to 1226 in f40d978
satisfied_children.len() == 1: DataFusion unconditionally selects that single satisfied child as the reference partitioning without checking its size relative to the unsatisfied children that will be adapted to it:datafusion/datafusion/physical-optimizer/src/ensure_requirements/enforce_distribution.rs
Lines 1185 to 1188 in f40d978
The Problem in Asymmetric Joins:
In an asymmetric join where only one table has a declared partition key matching the join condition (for example, a small dimension table with 100 rows is range-partitioned, but a large fact table with 100M rows is unpartitioned on that join key):
satisfied_childrencontains only the small dimension table (len == 1).ref_partitioning.adapt(...)) to match the small table's partition boundaries.Describe the solution you'd like
When
satisfied_children.len() == 1(or before selecting any reference child), compare thePlanSizeof the candidate satisfied reference child against thePlanSizeof the unsatisfied children that would be adapted to it.If an unsatisfied child is strictly larger than the satisfied reference child (
unsatisfied_size > reference_size):Noneforbest_satisfied_childso that the join falls back to standard symmetric distribution (e.g. symmetric hash repartitioning or broadcast), preventing an asymmetric 1-sided shuffle of the larger relation.Describe alternatives you've considered
Downstream query planners currently have to defend against this by artificially withholding / refusing to stamp partition metadata on smaller tables in asymmetric joins to prevent DataFusion from shuffling the larger partner to match the smaller table.
Having DataFusion check
PlanSizebefore adapting larger unsatisfied children to a smaller satisfied child would makeenforce_distribution_relationshipsrobust against asymmetric joins out of the box.Additional context
d109f1b
enforce_distribution.rs:datafusion/datafusion/physical-optimizer/src/ensure_requirements/enforce_distribution.rs
Lines 1181 to 1229 in f40d978