Repository navigation
Conversation
yjhjstz
marked this pull request as ready for review
November 2, 2026 19:06
Alena0704
self-requested a review
November 3, 2026 08:39
my-ship-it
approved these changes
Nov 4, 2026
my-ship-it
left a comment
Contributor
There was a problem hiding this comment.
Great work!
This memoization for child contexts and skipping redundant part-prop requests is a good optimization, and the benchmark results look really promising.
Alena0704
approved these changes
Nov 6, 2026
Alena0704
left a comment
Collaborator
There was a problem hiding this comment.
Thank you for your work on this! Looks good to me. Great job!
Hash and nested-loop joins create two partition propagation requests for every combination of their other property requests: request 0 may push DPE predicates to a child, request 1 passes the incoming requirement through. Parallel hash joins always create both, and so does every nested-loop join. When the join has no partition consumers below it and its parent requires no partition propagation, both requests produce an empty spec for every child. The second request then optimizes exactly the same child contexts as the first one, only for its cost context to be dropped as a duplicate. With parallel plans enabled this repeats a large share of the optimization jobs of every join group. Reject such requests in CEngine::FCheckReqdProps, before any child is optimized, and add CPartitionPropagationSpec::IsEmpty() for the check. Measured on a debug build with star, outer, semi, anti, aggregate, multi-key, union and DPE queries: plans and costs are unchanged, and ORCA planning time with parallel plans drops by 10-19% on the join-heavy queries. Claude-Session: https://claude.ai/code/session_01M1CxTMjApWd2XBG3C4wnyi Claude-Session: https://claude.ai/code/session_01ALBeQzzkBwDJDY1UJ65JrA (cherry picked from commit f4d28f67ae59dc572bb78d46b087b7cbc9bbec65)
A request of a group expression is optimized once per context of its group. Under contexts that differ only in the required distribution, it usually computes the same child requirements and reaches the same child contexts again, after computing every child requirement, looking up the child contexts, waiting for the child jobs and deriving the plan properties of each optimized child. Store the child contexts a request reaches on its group expression, keyed by the request number, the search stage and the parent's required plan properties apart from distribution. A later request with an equal key reuses them if it would reach the same contexts: - Every child requirement except distribution only depends on the matching part of the parent's requirements, which the key makes equal, and on the plans of the children optimized before, which are the best plans of the same contexts. Only Ped() sees the whole parent requirement, so the required distribution of each child is computed again and compared. The plan properties of earlier children are derived again for this, as DerivePrevChildProps() does: some PdsRequired() implementations change the derived distribution of the first child in place, and the properties cached on a cost context are shared. - A child context must have a plan, must not be the context itself, and must be the one a lookup of its requirements finds. A group can hold several contexts with equal requirements when a requirement changes after its context was inserted. The cost bound checks made after each child are repeated with the reused contexts. CTE sequences and multi-stage search are left out. The developer GUC optimizer_enable_child_opt_memo (default on) turns the memo off. optimizer_verify_child_opt_memo optimizes the children anyway and logs where the result differs from the reused contexts. optimizer_print_optimization_stats prints the memo counters. In 13 join and aggregation queries the plans are identical with and without the memo, and 11914 of 16127 lookups reuse child contexts with parallel plans (5020 of 7870 serial). Planning time drops by 12.6% geomean (15.4% in total) with parallel plans and by 8.3% (9.4%) serial. Verify mode finds no difference there or in 25 related regression tests, whose results do not change apart from run-to-run noise. Claude-Session: https://claude.ai/code/session_01M1CxTMjApWd2XBG3C4wnyi Claude-Session: https://claude.ai/code/session_01ALBeQzzkBwDJDY1UJ65JrA (cherry picked from commit 9bb35ccdd3c1e13809776bbe76189c1bc34175c4)
yjhjstz
force-pushed
the
feat/orca-child-opt-memo
branch
from
November 6, 2026 17:47
1ded742 to
9747b44
Compare
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.
Changes
CEngine::FCheckReqdPropsbefore any child is optimized.Ped) and checking that the child context has a plan, is not the context itself, and is the one a lookup of its requirements finds. As when the children are optimized, the plan properties of earlier children are derived again for the recheck, so it does not change the properties cached on their cost contexts. Cost bound checks after each child are replayed. CTE sequences and multi-stage search are left out.optimizer_enable_child_opt_memo(developer GUC, default on)optimizer_verify_child_opt_memo(developer GUC, default off): optimizes the children anyway and logs any difference from the reused contextsPlanning time
Baseline 13 join/aggregation/subquery/DPE queries. "Part-prop only" is HEAD with
optimizer_enable_child_opt_memo=off.Parallel/serial planning time ratio (geomean): 1.572 (baseline), 1.445 (part-prop only), 1.377 (HEAD).
What does this PR do?
Type of Change
Breaking Changes
Test Plan
make installcheckmake -C src/test installcheck-cbdb-parallelImpact
Performance:
User-facing changes:
Dependencies:
Checklist
Additional Context
CI Skip Instructions