diff options
author | Richard Guo <rguo@postgresql.org> | 2025-05-08 18:21:32 +0900 |
---|---|---|
committer | Richard Guo <rguo@postgresql.org> | 2025-05-08 18:21:32 +0900 |
commit | c06e909c26f070dee78f73c35565d6f4a4ffdcda (patch) | |
tree | 9f69470d8ba03027f37796542b8c0e7bafb2f44e /src/backend/optimizer/plan/createplan.c | |
parent | 773db22269d474fab46d25e9e15b1e55252cf92c (diff) | |
download | postgresql-c06e909c26f070dee78f73c35565d6f4a4ffdcda.tar.gz postgresql-c06e909c26f070dee78f73c35565d6f4a4ffdcda.zip |
Track the number of presorted outer pathkeys in MergePath
When creating an explicit Sort node for the outer path of a mergejoin,
we need to determine the number of presorted keys of the outer path to
decide whether explicit incremental sort can be applied. Currently,
this is done by repeatedly calling pathkeys_count_contained_in.
This patch caches the number of presorted outer pathkeys in MergePath,
allowing us to save several calls to pathkeys_count_contained_in. It
can be considered a complement to the changes in commit 828e94c9d.
Reported-by: David Rowley <dgrowleyml@gmail.com>
Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Tender Wang <tndrwang@gmail.com>
Discussion: https://postgr.es/m/CAApHDvqvBireB_w6x8BN5txdvBEHxVgZBt=rUnpf5ww5P_E_ww@mail.gmail.com
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index a8f22a8c154..4ad30b7627e 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -4521,48 +4521,41 @@ create_mergejoin_plan(PlannerInfo *root, { Relids outer_relids = outer_path->parent->relids; Plan *sort_plan; - bool use_incremental_sort = false; - int presorted_keys; + + /* + * We can assert that the outer path is not already ordered + * appropriately for the mergejoin; otherwise, outersortkeys would + * have been set to NIL. + */ + Assert(!pathkeys_contained_in(best_path->outersortkeys, + outer_path->pathkeys)); /* * We choose to use incremental sort if it is enabled and there are * presorted keys; otherwise we use full sort. */ - if (enable_incremental_sort) - { - bool is_sorted PG_USED_FOR_ASSERTS_ONLY; - - is_sorted = pathkeys_count_contained_in(best_path->outersortkeys, - outer_path->pathkeys, - &presorted_keys); - Assert(!is_sorted); - - if (presorted_keys > 0) - use_incremental_sort = true; - } - - if (!use_incremental_sort) - { - sort_plan = (Plan *) - make_sort_from_pathkeys(outer_plan, - best_path->outersortkeys, - outer_relids); - - label_sort_with_costsize(root, (Sort *) sort_plan, -1.0); - } - else + if (enable_incremental_sort && best_path->outer_presorted_keys > 0) { sort_plan = (Plan *) make_incrementalsort_from_pathkeys(outer_plan, best_path->outersortkeys, outer_relids, - presorted_keys); + best_path->outer_presorted_keys); label_incrementalsort_with_costsize(root, (IncrementalSort *) sort_plan, best_path->outersortkeys, -1.0); } + else + { + sort_plan = (Plan *) + make_sort_from_pathkeys(outer_plan, + best_path->outersortkeys, + outer_relids); + + label_sort_with_costsize(root, (Sort *) sort_plan, -1.0); + } outer_plan = sort_plan; outerpathkeys = best_path->outersortkeys; @@ -4578,9 +4571,19 @@ create_mergejoin_plan(PlannerInfo *root, */ Relids inner_relids = inner_path->parent->relids; - Sort *sort = make_sort_from_pathkeys(inner_plan, - best_path->innersortkeys, - inner_relids); + Sort *sort; + + /* + * We can assert that the inner path is not already ordered + * appropriately for the mergejoin; otherwise, innersortkeys would + * have been set to NIL. + */ + Assert(!pathkeys_contained_in(best_path->innersortkeys, + inner_path->pathkeys)); + + sort = make_sort_from_pathkeys(inner_plan, + best_path->innersortkeys, + inner_relids); label_sort_with_costsize(root, sort, -1.0); inner_plan = (Plan *) sort; |