better_width_estimates_for_union_queries.patch

application/octet-stream

Filename: better_width_estimates_for_union_queries.patch
Type: application/octet-stream
Part: 0
Message: Re: The issue of incorrect width estimation in UNION queries

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.