From 2cc007fd0359870b4a1e959af0ac94e61df47240 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Sat, 15 Jan 2022 02:15:23 +0100 Subject: Ignore extended statistics for inheritance trees Since commit 859b3003de we only build extended statistics for individual relations, ignoring the child relations. This resolved the issue with updating catalog tuple twice, but we still tried to use the statistics when calculating estimates for the whole inheritance tree. When the relations contain very distinct data, it may produce bogus estimates. This is roughly the same issue 427c6b5b9 addressed ~15 years ago, and we fix it the same way - by ignoring extended statistics when calculating estimates for the inheritance tree as a whole. We still consider extended statistics when calculating estimates for individual child relations, of course. This may result in plan changes due to different estimates, but if the old statistics were not describing the inheritance tree particularly well it's quite likely the new plans is actually better. Report and patch by Justin Pryzby, minor fixes and cleanup by me. Backpatch all the way back to PostgreSQL 10, where extended statistics were introduced (same as 859b3003de). Author: Justin Pryzby Reported-by: Justin Pryzby Backpatch-through: 10 Discussion: https://postgr.es/m/20210923212624.GI831%40telsasoft.com --- src/backend/utils/adt/selfuncs.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/backend/utils/adt/selfuncs.c') diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 10895fb2876..1010d5caa86 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -3913,6 +3913,14 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, Oid statOid = InvalidOid; MVNDistinct *stats; StatisticExtInfo *matched_info = NULL; + RangeTblEntry *rte = planner_rt_fetch(rel->relid, root); + + /* + * When dealing with inheritance trees, ignore extended stats (which were + * built without data from child rels, and thus do not represent them). + */ + if (rte->inh) + return false; /* bail out immediately if the table has no extended statistics */ if (!rel->statlist) @@ -5222,6 +5230,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, foreach(slist, onerel->statlist) { StatisticExtInfo *info = (StatisticExtInfo *) lfirst(slist); + RangeTblEntry *rte = planner_rt_fetch(onerel->relid, root); ListCell *expr_item; int pos; @@ -5232,6 +5241,14 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, if (vardata->statsTuple) break; + /* + * When dealing with inheritance trees, ignore extended stats (which + * were built without data from child rels, and so do not represent + * them). + */ + if (rte->inh) + break; + /* skip stats without per-expression stats */ if (info->kind != STATS_EXT_EXPRESSIONS) continue; -- cgit v1.2.3