From 8439b4818410d860a4ca4be3458b54c04c6f8648 Mon Sep 17 00:00:00 2001 From: Andy Fan Date: Tue, 1 Feb 2022 15:20:10 +0800 Subject: [PATCH v2 3/6] Introduce RelOptInfo.filtered_rows. Previously the Path.rows (shown in the explain output) and RelOptInfo.rows which would be used to calculating joinrel's estimated rows. They are same at many scan paths, like SeqScan, IndexScan, BitmapHeapScan and so on. But they would be different after distributing a new restrictinfo from ec_filter. So I developed RelOptInfo.filtered_rows to take the duty out of RelOptInfo.rows. --- src/backend/optimizer/path/costsize.c | 21 ++++++++++++++++----- src/include/nodes/pathnodes.h | 2 ++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 9e303877af7..b1117257a38 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -241,7 +241,7 @@ cost_seqscan(Path *path, PlannerInfo *root, if (param_info) path->rows = param_info->ppi_rows; else - path->rows = baserel->rows; + path->rows = baserel->filtered_rows; if (!enable_seqscan) startup_cost += disable_cost; @@ -539,7 +539,7 @@ cost_index(IndexPath *path, PlannerInfo *root, double loop_count, } else { - path->path.rows = baserel->rows; + path->path.rows = baserel->filtered_rows; /* qpquals come from just the rel's restriction clauses */ qpquals = extract_nonindex_conditions(path->indexinfo->indrestrictinfo, path->indexclauses); @@ -978,7 +978,7 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel, if (param_info) path->rows = param_info->ppi_rows; else - path->rows = baserel->rows; + path->rows = baserel->filtered_rows; if (!enable_bitmapscan) startup_cost += disable_cost; @@ -1209,7 +1209,7 @@ cost_tidscan(Path *path, PlannerInfo *root, if (param_info) path->rows = param_info->ppi_rows; else - path->rows = baserel->rows; + path->rows = baserel->filtered_rows; /* Count how many tuples we expect to retrieve */ ntuples = 0; @@ -1320,7 +1320,7 @@ cost_tidrangescan(Path *path, PlannerInfo *root, if (param_info) path->rows = param_info->ppi_rows; else - path->rows = baserel->rows; + path->rows = baserel->filtered_rows; /* Count how many tuples and pages we expect to scan */ selectivity = clauselist_selectivity(root, tidrangequals, baserel->relid, @@ -4938,6 +4938,17 @@ set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel) rel->rows = clamp_row_est(nrows); + nrows = rel->tuples * + clauselist_selectivity_ext(root, + rel->baserestrictinfo, + 0, + JOIN_INNER, + NULL, + true, + true /* include_derived, for filtered rows */); + + rel->filtered_rows = clamp_row_est(nrows); + cost_qual_eval(&rel->baserestrictcost, rel->baserestrictinfo, root); set_rel_width(root, rel); diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 42368e10b8e..dbe1775f96d 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -683,6 +683,8 @@ typedef struct RelOptInfo /* size estimates generated by planner */ Cardinality rows; /* estimated number of result tuples */ + Cardinality filtered_rows; /* filtered rows */ + /* per-relation planner control flags */ bool consider_startup; /* keep cheap-startup-cost paths? */ bool consider_param_startup; /* ditto, for parameterized paths? */ -- 2.21.0