From 5b0bc386f1ab60d528c12491640400fa2e1b72fc Mon Sep 17 00:00:00 2001 From: Yuya Watari Date: Thu, 20 Oct 2022 15:46:00 +0900 Subject: [PATCH v8 3/3] Use conventional algorithm for smaller size cases --- src/backend/optimizer/path/pathkeys.c | 58 ++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index be11e1c053..8426d2681a 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -1434,9 +1434,6 @@ select_outer_pathkeys_for_merge(PlannerInfo *root, { RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); EquivalenceClass *oeclass; - Bitmapset *matching_ems; - Bitmapset *interesting_ems; - Bitmapset *other_parent_ems; /* get the outer eclass */ update_mergeclause_eclasses(root, rinfo); @@ -1455,14 +1452,57 @@ select_outer_pathkeys_for_merge(PlannerInfo *root, if (j < necs) continue; - /* compute score */ - matching_ems = get_ecmember_indexes(root, oeclass, joinrel->relids, false, false); - other_parent_ems = bms_difference(oeclass->ec_nonchild_indexes, oeclass->ec_norel_indexes); - interesting_ems = bms_difference(other_parent_ems, matching_ems); + /* Compute score */ + /* + * We use two different algorithms depending on the size of the + * problem. For small sizes, linear search is preferable, while + * optimization based on bitmap sets is faster for larger sizes. + */ + /* + * TODO: Switching two algorithms is not ideal and may be ugly + * because it introduces code duplication. Is there a better way? + */ + /* + * TODO: 32 is a magic number. Do we have to declare it as a constant + * macro? + */ + if (root->simple_rel_array_size < 32) + { + int score; + int k; + + /* compute score */ + score = 0; + k = -1; + while ((k = bms_next_member(oeclass->ec_member_indexes, k)) >= 0) + { + EquivalenceMember *em = list_nth_node(EquivalenceMember, + root->eq_members, k); + + /* Potential future join partner? */ + if (!em->em_is_const && !em->em_is_child && + !bms_overlap(em->em_relids, joinrel->relids)) + score++; + } + + scores[necs] = score; + } + else + { + Bitmapset *matching_ems; + Bitmapset *interesting_ems; + Bitmapset *other_parent_ems; + + /* compute score */ + matching_ems = get_ecmember_indexes(root, oeclass, joinrel->relids, false, false); + other_parent_ems = bms_difference(oeclass->ec_nonchild_indexes, oeclass->ec_norel_indexes); + interesting_ems = bms_difference(other_parent_ems, matching_ems); + + /* record results */ + scores[necs] = bms_num_members(interesting_ems); + } - /* record results */ ecs[necs] = oeclass; - scores[necs] = bms_num_members(interesting_ems); necs++; } -- 2.35.3.windows.1