v9-0003-Use-conventional-algorithm-for-smaller-size-cases.patch
application/octet-stream
Filename: v9-0003-Use-conventional-algorithm-for-smaller-size-cases.patch
Type: application/octet-stream
Part: 2
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v9-0003
Subject: Use conventional algorithm for smaller size cases
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/pathkeys.c | 49 | 9 |
From b85289b511ed8242f08e83d8132070eb0a64d9be Mon Sep 17 00:00:00 2001
From: Yuya Watari <watari.yuya@gmail.com>
Date: Thu, 20 Oct 2022 15:46:00 +0900
Subject: [PATCH v9 3/4] 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