better_width_estimates_for_union_queries.patch
application/octet-stream
Filename: better_width_estimates_for_union_queries.patch
Type: application/octet-stream
Part: 0
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: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/prep/prepunion.c | 18 | 0 |
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 28a4ae64440..f5e82b7c68d 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -696,6 +696,8 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root,
Path *gpath = NULL;
bool try_sorted = false;
List *union_pathkeys = NIL;
+ double parent_rows;
+ double parent_size;
/*
* If any of my children are identical UNION nodes (same op, all-flag, and
@@ -807,6 +809,22 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root,
result_rel->consider_parallel = consider_parallel;
result_rel->consider_startup = (root->tuple_fraction > 0);
+ /*
+ * Attempt to estimate the width of the result_rel's PathTarget by
+ * proportioning the width of the union child PathTargets over the
+ * estimated number of rows.
+ */
+ parent_rows = 0;
+ parent_size = 0;
+ foreach(lc, cheapest_pathlist)
+ {
+ Path *path = (Path *) lfirst(lc);
+
+ parent_rows += path->rows;
+ parent_size += path->parent->reltarget->width * path->rows;
+ }
+ result_rel->reltarget->width = rint(parent_size / parent_rows);
+
/*
* Append the child results together using the cheapest paths from each
* union child.