Uh oh!
There was an error while loading. Please reload this page.
[SPARK-30036][SQL] Fix: REPARTITION hint does not work with order by - #26946
[SPARK-30036][SQL] Fix: REPARTITION hint does not work with order by#26946jackylee-ch wants to merge 8 commits into
Conversation
Change-Id: I9ec887eece29abed048192b559f7d69a9e67afe3
Change-Id: If6b4c1f818c38b1862f69acc63f79feea127bbee
Change-Id: Ieb757a218588e2f35efd1b0eac4d076fb75eb1c8
jackylee-ch
commented
Dec 19, 2019
ulysses-you
commented
Dec 19, 2019
I think we should add check at |
cloud-fan
commented
Dec 19, 2019
ok to test |
@ulysses-you Adding RangePartitioning doesn't happen in optimizer, thus we can't check this in |
SparkQA
commented
Dec 19, 2019
Test build #115563 has finished for PR 26946 at commit
|
| case (ShuffleExchangeExec(partitioning: RoundRobinPartitioning, child, _), | ||
| distribution: OrderedDistribution) => | ||
| ShuffleExchangeExec( | ||
| distribution.createPartitioning(partitioning.numPartitions), child) |
There was a problem hiding this comment.
Could you update like the following, @stczwd ?
-case (ShuffleExchangeExec(partitioning: RoundRobinPartitioning, child, _),
-distribution: OrderedDistribution) =>-ShuffleExchangeExec(
- distribution.createPartitioning(partitioning.numPartitions), child)
+case (ShuffleExchangeExec(partitioning, child, _), distribution) =>+ShuffleExchangeExec(distribution.createPartitioning(partitioning.numPartitions), child)There was a problem hiding this comment.
You means this should work in other Partitioning? Let me run some test for it.
There was a problem hiding this comment.
thanks, i have change my code
| DummySparkPlan(outputPartitioning = partitioning))) | ||
| val outputPlan = EnsureRequirements(spark.sessionState.conf).apply(inputPlan) | ||
| assert(outputPlan.find{ | ||
| case e: ShuffleExchangeExec => e.outputPartitioning.isInstanceOf[RoundRobinPartitioning] |
There was a problem hiding this comment.
-casee: ShuffleExchangeExec=> e.outputPartitioning.isInstanceOf[RoundRobinPartitioning]
+caseShuffleExchangeExec(_: RoundRobinPartitioning, _, _) =>true| partitioning, | ||
| DummySparkPlan(outputPartitioning = partitioning))) | ||
| val outputPlan = EnsureRequirements(spark.sessionState.conf).apply(inputPlan) | ||
| assert(outputPlan.find{ |
dongjoon-hyun
commented
Dec 19, 2019
I updated the PR description a little, @stczwd . |
| child | ||
| case (child, BroadcastDistribution(mode)) => | ||
| BroadcastExchangeExec(mode, child) | ||
| case (ShuffleExchangeExec(partitioning: RoundRobinPartitioning, child, _), |
There was a problem hiding this comment.
How about use Partitioning instead of RoundRobinPartitioning . Since we already support this SELECT /*+ REPARTITION(5, a) */ * FROM test ORDER BY a.
There was a problem hiding this comment.
thanks, I will change it
| } | ||
| test("SPARK-30036: EnsureRequirements replace Exchange " + | ||
| "if child has SortExec and RoundRobinPartitioning") { |
There was a problem hiding this comment.
How about just saying Remove unnecessary RoundRobinPartitioning in the test title? Also, can you make the PR title obivious, too?
There was a problem hiding this comment.
Good for test title, thanks.
But it is not suitable for PR title, there are other situations in this titile.
There was a problem hiding this comment.
How about Avoid RoundRobinPartitioning that EnsureRequirements Redundantly adds?
There was a problem hiding this comment.
Because HashPartitioning should also be concerned.
jackylee-ch
commented
Dec 20, 2019
@dongjoon-hyun thanks |
Change-Id: I6b102f32b4084625875b395990e8ac4673c56bac
SparkQA
commented
Dec 20, 2019
Test build #115598 has finished for PR 26946 at commit
|
Uh oh!
There was an error while loading. Please reload this page.
| val outputPlan = EnsureRequirements(spark.sessionState.conf).apply(inputPlan) | ||
| assert(outputPlan.find { | ||
| case ShuffleExchangeExec(_: RoundRobinPartitioning, _, _) => true | ||
| case _ => false}.isEmpty, |
There was a problem hiding this comment.
nit:
...find {
case ...
case ...
}.isEmpty
| val outputPlan = EnsureRequirements(spark.sessionState.conf).apply(inputPlan) | ||
| assert(outputPlan.find { | ||
| case ShuffleExchangeExec(_: HashPartitioning, _, _) => true | ||
| case _ => false}.isEmpty, |
cloud-fan
commented
Dec 20, 2019
shall we add an end-to-end test for |
jackylee-ch
commented
Dec 20, 2019
|
Change-Id: I0b55a61e1a9ac3555177322ac44d2b216d45bd24
SparkQA
commented
Dec 20, 2019
Test build #115630 has finished for PR 26946 at commit
|
| case (ShuffleExchangeExec(partitioning, child, _), distribution: OrderedDistribution) => | ||
| ShuffleExchangeExec(distribution.createPartitioning(partitioning.numPartitions), child) |
There was a problem hiding this comment.
This considers a special case for OrderedDistribution. Generally, if ShuffleExchangeExec is followed by any unsatisfying distribution , we should always trim the ShuffleExchangeExec and apply the partitioning of distribution. Don't we?
There was a problem hiding this comment.
Sound reasonable. Any suitable cases?
There was a problem hiding this comment.
I just tried few possible cases, but can not have a concrete case like this. Maybe this is the only case possibly. So I think this should be fine.
cloud-fan
commented
Dec 23, 2019
We can add an end-to-end test, check the physical plan of a query, and count shuffles. |
Sure,I will add some tests for these cases. |
| // Range has range partitioning in its output now. To have a range shuffle, we | ||
| // need to run a repartition first. | ||
| val data = spark.range(0, n, 1, 1).repartition(10).sort($"id".desc) | ||
| // Range has range partitioning in its output now. |
There was a problem hiding this comment.
shall we remove this comment now? it's not useful as we do add shuffle, the range output partitioning doesn't matter.
| withSQLConf(SQLConf.SHUFFLE_PARTITIONS.key -> numPartitions.toString) { | ||
| // The default chi-sq value should be low | ||
| assert(computeChiSquareTest() < 100) | ||
| assert(computeChiSquareTest() < 10) |
There was a problem hiding this comment.
the physical plan is same as before, what caused this change?
There was a problem hiding this comment.
They are not same, we had two shuffles before, one was RoundRobinPartitioning, the other was RangePartitioning.
SparkQA
commented
Dec 24, 2019
Test build #115689 has finished for PR 26946 at commit
|
cloud-fan
commented
Dec 24, 2019
retest this please |
| } | ||
| } | ||
| test("SPARK-30036: Romove unnecessary RoundRobinPartitioning " + |
Change-Id: I175b3824ba9ce46fba0ebba6ebf0b220d64de42c
HyukjinKwon
commented
Dec 24, 2019
Looks fine to me |
SparkQA
commented
Dec 24, 2019
Test build #115719 has finished for PR 26946 at commit
|
HyukjinKwon
commented
Dec 24, 2019
retest this please |
SparkQA
commented
Dec 24, 2019
Test build #115718 has finished for PR 26946 at commit
|
SparkQA
commented
Dec 24, 2019
Test build #115729 has finished for PR 26946 at commit
|
cloud-fan
commented
Dec 25, 2019
retest this please |
SparkQA
commented
Dec 25, 2019
Test build #115766 has finished for PR 26946 at commit
|
HyukjinKwon
commented
Dec 27, 2019
Merged to master, I guess :-). |
cloud-fan
commented
Dec 27, 2019
yea merged to master! |
Wait, another point. And then there is a little difference between The last, if end user really want result partition is 10, should use |
cloud-fan
commented
Jan 3, 2020
for join, it doesn't require This PR only affects sort. |
jackylee-ch
commented
Jan 3, 2020
df.sort("id").repartition(10) returns wrong result. Global sort result would be repartitioned with disordered. |
ulysses-you
commented
Jan 4, 2020
Yes it is. But it is similar with outer join. |
ulysses-you
commented
Jan 4, 2020
Sorry for the wrong example. I mean user should use the right way to change partition. Obviously |
jackylee-ch
commented
Jan 6, 2020
Thanks for pay attention on this. The main problem you described is whether we should change partition num for OrderedDistribution. Correct me if I'm wrong. Thanks |
I see you want to make a way that change partition easily after sort. Only one thing I not sure. If I don not know how committer think about it, or it's just fine. |
cloud-fan
commented
Jan 6, 2020
what It's more efficient to shuffle only once for query For |
maryannxue
commented
Jan 27, 2020
Think we should revert this PR. The change in test |
cloud-fan
commented
Jan 31, 2020
After more thoughts, I think it's wrong to use optimization to fix a bug. Looking into the bug, the issue is: the I think #27096 is in the right way to optimize redundant shuffles, but we still need to fix the bug about how to handle hints in the parser. I'm reverting this. Let's fix the bug in the parser. |
### Why are the changes needed? `EnsureRequirements` adds `ShuffleExchangeExec` (RangePartitioning) after Sort if `RoundRobinPartitioning` behinds it. This will cause 2 shuffles, and the number of partitions in the final stage is not the number specified by `RoundRobinPartitioning. **Example SQL** ``` SELECT /*+ REPARTITION(5) */ * FROM test ORDER BY a ``` **BEFORE** ``` == Physical Plan == *(1) Sort [a#0 ASC NULLS FIRST], true, 0 +- Exchange rangepartitioning(a#0 ASC NULLS FIRST, 200), true, [id=apache#11] +- Exchange RoundRobinPartitioning(5), false, [id=apache#9] +- Scan hive default.test [a#0, b#1], HiveTableRelation `default`.`test`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#0, b#1] ``` **AFTER** ``` == Physical Plan == *(1) Sort [a#0 ASC NULLS FIRST], true, 0 +- Exchange rangepartitioning(a#0 ASC NULLS FIRST, 5), true, [id=apache#11] +- Scan hive default.test [a#0, b#1], HiveTableRelation `default`.`test`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#0, b#1] ``` ### Does this PR introduce any user-facing change? No ### How was this patch tested? Run suite Tests and add new test for this. Closesapache#26946 from stczwd/RoundRobinPartitioning. Lead-authored-by: lijunqing <lijunqing@baidu.com> Co-authored-by: stczwd <qcsd2011@163.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com>
Why are the changes needed?
EnsureRequirementsaddsShuffleExchangeExec(RangePartitioning) after Sort ifRoundRobinPartitioningbehinds it. This will cause 2 shuffles, and the number of partitions in the final stage is not the number specified by `RoundRobinPartitioning.Example SQL
BEFORE
AFTER
Does this PR introduce any user-facing change?
No
How was this patch tested?
Run suite Tests and add new test for this.