[SPARK-36082][SQL][FOLLOWUP] Restore NAAJ broadcast hash join by default - #58631
Open
cloud-fan wants to merge 3 commits into
Open
[SPARK-36082][SQL][FOLLOWUP] Restore NAAJ broadcast hash join by default#58631cloud-fan wants to merge 3 commits into
cloud-fan wants to merge 3 commits into
Conversation
Use a dedicated NAAJ broadcast threshold, defaulting to Long.MaxValue, so size-based nested-loop fallback is an explicit tuning choice. Retain the independent AQE broadcast-mode correctness checks.
cloud-fan
force-pushed
the
cloud-fan/revert-naaj-oom-protection
branch
from
September 9, 2026 08:00
45b90b0 to
17065c9
Compare
Contributor
Author
|
cc @sunchao |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this pull request?
This PR follows #55678 and
#58404.
It restores the original planning behavior for the optimized single-column null-aware anti join
(NAAJ): by default, Spark selects the specialized null-aware
BroadcastHashJoinExecand buildsthe right side independently of
spark.sql.autoBroadcastJoinThreshold.It adds the internal
spark.sql.nullAwareAntiJoinBroadcastThresholdconfiguration as an explicittuning option. The configuration defaults to
Long.MaxValue, preserving the original behavior.When the estimated right-side size exceeds the configured value, Spark skips the specialized hash
path and falls through to regular join planning. Setting it to
-1always skips the specializedhash path.
The AQE broadcast-mode validation introduced in #55678 is retained. The PR removes the additional
NAAJ fallback decision and optimizer plumbing introduced in #58404.
Why are the changes needed?
#55678 made the NAAJ hash optimization conditional on the general automatic broadcast threshold,
and #58404 added planning logic to preserve the exact nested-loop fallback and its build side.
However, the automatic broadcast threshold and plan statistics are cost-planning heuristics; they
do not prove that either input can be materialized and broadcast safely.
Spark does not have a shuffle-capable NAAJ implementation. When regular join planning chooses the
right side for the fallback,
BroadcastNestedLoopJoinExecstill broadcasts that same input whilechanging hash lookup from
O(M + N)to nested-loop evaluation atO(M * N). This may replace abroadcast failure with a much longer-running query without eliminating the memory risk.
When the right side exceeds the new threshold, regular join planning may choose a build-left
nested-loop join if the left side is estimated to be broadcastable. This can avoid broadcasting
the right side, but it is only best-effort: the estimate may be inaccurate, and the fallback may
still OOM or run in
O(M * N)time. A generally scalable solution for large NAAJs still requiresa non-broadcast implementation.
Does this PR introduce any user-facing change?
Yes. Compared with the current behavior, the optimized single-column NAAJ uses the null-aware
broadcast hash join by default even when the estimated right side exceeds
spark.sql.autoBroadcastJoinThreshold.Users who need the size-based fallback can set
spark.sql.nullAwareAntiJoinBroadcastThreshold. Its default value isLong.MaxValue, so thedefault behavior is the same as before #55678.
How was this patch tested?
Added coverage to
JoinSelectionHelperSuiteshowing that the default NAAJ threshold is independentof
spark.sql.autoBroadcastJoinThresholdand that an explicitly configured threshold rejects anoversized right side.
Added coverage to
JoinSuiteshowing that an explicit NAAJ threshold enables the build-leftnested-loop fallback for a small-left/large-right query.
The tests were not run locally.
Was this patch authored or co-authored using generative AI tooling?
Generated-by: OpenAI Codex (GPT-5)