-
Notifications
You must be signed in to change notification settings - Fork 29.3k
[SPARK-58084][SQL] Support converting sort merge join to shuffled hash join in AQE physical plan #57181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
[SPARK-58084][SQL] Support converting sort merge join to shuffled hash join in AQE physical plan #57181
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1337,6 +1337,46 @@ object SQLConf { | |
| .bytesConf(ByteUnit.BYTE) | ||
| .createWithDefault(0L) | ||
|
|
||
| val ADAPTIVE_CONVERT_SORT_MERGE_JOIN_TO_SHUFFLED_HASH_JOIN_ENABLED = | ||
| buildConf("spark.sql.adaptive.convertSortMergeJoinToShuffledHashJoin.enabled") | ||
| .doc("When true, Spark converts a sort merge join to a shuffled hash join during adaptive " + | ||
| "execution when the build side's materialized per-partition sizes are all within " + | ||
| s"${ADAPTIVE_MAX_SHUFFLE_HASH_JOIN_LOCAL_MAP_THRESHOLD.key} (which additionally requires " + | ||
| s"${ADVISORY_PARTITION_SIZE_IN_BYTES.key} to not be larger than it), even when " + | ||
| "non-shuffle operators sit between the join and its input shuffle.") | ||
| .version("4.3.0") | ||
| .withBindingPolicy(ConfigBindingPolicy.SESSION) | ||
| .booleanConf | ||
| .createWithDefault(false) | ||
|
|
||
| val ADAPTIVE_CONVERT_SORT_MERGE_JOIN_TO_SHUFFLED_HASH_JOIN_MIN_WIDENING_FACTOR = | ||
| buildConf("spark.sql.adaptive.convertSortMergeJoinToShuffledHashJoin.minWideningFactor") | ||
| .doc("The lower bound applied to the row-widening factor used by " + | ||
| s"${ADAPTIVE_CONVERT_SORT_MERGE_JOIN_TO_SHUFFLED_HASH_JOIN_ENABLED.key} when bounding a " + | ||
| "build side's shuffled hash map size. The factor scales the input shuffle bytes by the " + | ||
| "estimated per-row size growth of the operators between the join and its shuffle; a " + | ||
| "larger lower bound is more conservative and makes the conversion less likely when " + | ||
| "statistics may under-estimate the build size. Must be positive.") | ||
| .version("4.3.0") | ||
| .withBindingPolicy(ConfigBindingPolicy.SESSION) | ||
| .doubleConf | ||
| .checkValue(_ > 0, "The minimum widening factor must be positive.") | ||
| .createWithDefault(1.0) | ||
|
|
||
| val ADAPTIVE_COST_EVALUATOR_COUNT_LOCAL_SORT_ENABLED = | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enabling only
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Made |
||
| buildConf("spark.sql.adaptive.costEvaluator.countLocalSort.enabled") | ||
| .doc("When true, the default AQE cost evaluator also counts the number of local sorts as a " + | ||
| "lower-priority tiebreaker below the number of shuffles. This lets adaptive execution " + | ||
| "prefer a plan with fewer local sorts among plans with the same number of shuffles, for " + | ||
| s"example a shuffled hash join produced by " + | ||
| s"${ADAPTIVE_CONVERT_SORT_MERGE_JOIN_TO_SHUFFLED_HASH_JOIN_ENABLED.key} over a " + | ||
| "sort merge join when the conversion does not push extra sorts elsewhere. Defaults to " + | ||
| s"${ADAPTIVE_CONVERT_SORT_MERGE_JOIN_TO_SHUFFLED_HASH_JOIN_ENABLED.key} so that it is " + | ||
| "enabled together with that conversion.") | ||
| .version("4.3.0") | ||
| .withBindingPolicy(ConfigBindingPolicy.SESSION) | ||
| .fallbackConf(ADAPTIVE_CONVERT_SORT_MERGE_JOIN_TO_SHUFFLED_HASH_JOIN_ENABLED) | ||
|
|
||
| val ADAPTIVE_OPTIMIZE_SKEWS_IN_REBALANCE_PARTITIONS_ENABLED = | ||
| buildConf("spark.sql.adaptive.optimizeSkewsInRebalancePartitions.enabled") | ||
| .doc(s"When true and '${ADAPTIVE_EXECUTION_ENABLED.key}' is true, Spark will optimize the " + | ||
|
|
@@ -8090,6 +8130,15 @@ class SQLConf extends Serializable with Logging with SqlApiConf { | |
| def nonEmptyPartitionRatioForBroadcastJoin: Double = | ||
| getConf(NON_EMPTY_PARTITION_RATIO_FOR_BROADCAST_JOIN) | ||
|
|
||
| def convertSortMergeJoinToShuffledHashJoinEnabled: Boolean = | ||
| getConf(ADAPTIVE_CONVERT_SORT_MERGE_JOIN_TO_SHUFFLED_HASH_JOIN_ENABLED) | ||
|
|
||
| def convertSortMergeJoinToShuffledHashJoinMinWideningFactor: Double = | ||
| getConf(ADAPTIVE_CONVERT_SORT_MERGE_JOIN_TO_SHUFFLED_HASH_JOIN_MIN_WIDENING_FACTOR) | ||
|
|
||
| def costEvaluatorCountLocalSortEnabled: Boolean = | ||
| getConf(ADAPTIVE_COST_EVALUATOR_COUNT_LOCAL_SORT_ENABLED) | ||
|
|
||
| def coalesceShufflePartitionsEnabled: Boolean = getConf(COALESCE_PARTITIONS_ENABLED) | ||
|
|
||
| def minBatchesToRetain: Int = getConf(MIN_BATCHES_TO_RETAIN) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this entry only mentions the per-partition size condition, but
preferShuffledHashJoinalso requiresspark.sql.adaptive.advisoryPartitionSizeInBytes <= maxShuffledHashJoinLocalMapThreshold, which is worth mentioning like the existing 3.2.0 entry above does.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated - the entry now notes that
preferShuffledHashJoinalso requiresspark.sql.adaptive.advisoryPartitionSizeInBytesto not be larger thanmaxShuffledHashJoinLocalMapThreshold, mirroring the 3.2.0 entry. Also added the two new configs to the table.