From 3bdf95317a5dc082f71b3d40d5700dffce618317 Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Fri, 24 Jan 2025 16:07:22 +0900 Subject: [PATCH v1] Adjust tuples estimate for appendrels In set_append_rel_size(), we currently set rel->tuples to rel->rows for an appendrel. Generally, rel->tuples is the raw number of tuples in the relation and rel->rows is the estimated number of tuples after the relation's restriction clauses have been applied. Although an appendrel itself doesn't directly enforce any quals today, its child relations may. Therefore, setting rel->tuples equal to rel->rows for an appendrel isn't always appropriate. Doing so can lead to issues in cost estimates in some cases. For instance, when estimating the number of distinct values from an appendrel, we would not be able to adjust the estimate based on the restriction selectivity. This patch addresses this by setting an appendrel's tuples to the total number of tuples accumulated from each live child, which better aligns with reality. --- src/backend/optimizer/path/allpaths.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 1115ebeee2..a13331c269 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -958,6 +958,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, { int parentRTindex = rti; bool has_live_children; + double parent_tuples; double parent_rows; double parent_size; double *parent_attrsizes; @@ -995,6 +996,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, * have zero rows and/or width, if they were excluded by constraints. */ has_live_children = false; + parent_tuples = 0; parent_rows = 0; parent_size = 0; nattrs = rel->max_attr - rel->min_attr + 1; @@ -1161,6 +1163,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, */ Assert(childrel->rows > 0); + parent_tuples += childrel->tuples; parent_rows += childrel->rows; parent_size += childrel->reltarget->width * childrel->rows; @@ -1207,17 +1210,12 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, int i; Assert(parent_rows > 0); + rel->tuples = parent_tuples; rel->rows = parent_rows; rel->reltarget->width = rint(parent_size / parent_rows); for (i = 0; i < nattrs; i++) rel->attr_widths[i] = rint(parent_attrsizes[i] / parent_rows); - /* - * Set "raw tuples" count equal to "rows" for the appendrel; needed - * because some places assume rel->tuples is valid for any baserel. - */ - rel->tuples = parent_rows; - /* * Note that we leave rel->pages as zero; this is important to avoid * double-counting the appendrel tree in total_table_pages. -- 2.43.0