From fc369280662c9183ccc50ac4ded144acadd84c15 Mon Sep 17 00:00:00 2001 From: Enrique Sanchez Cardoso Date: Sun, 24 May 2026 14:40:39 +0200 Subject: [PATCH 3/4] Extend multicolumn MCV cap to partial IN/ANY matches --- src/backend/statistics/extended_stats.c | 5 +---- src/backend/statistics/mcv.c | 17 ++++++++++------- src/test/regress/expected/stats_ext.out | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index f8c38653bf9..da6f6315698 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -2016,10 +2016,7 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli mcv_basesel, mcv_totalsel); - /* - * Cap to the least common MCV frequency when no MCV items - * matched. - */ + /* Cap the contribution of values not found in the MCV. */ if (stat_sel > mcv_cap) stat_sel = mcv_cap; diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c index 2e75f19d8bd..62761c58e33 100644 --- a/src/backend/statistics/mcv.c +++ b/src/backend/statistics/mcv.c @@ -1526,8 +1526,8 @@ pg_mcv_list_send(PG_FUNCTION_ARGS) /* * mcv_cap_multiplier - * Compute a multiplier for capping combined selectivity to the least - * common MCV frequency when no MCV items matched. + * Compute a multiplier for capping combined selectivity to the least + * common MCV frequency. * * Returns 0 if the cap should not be applied (unsupported clause types). * Returns >= 1 as the number of distinct value combinations the clauses @@ -2105,6 +2105,7 @@ mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat, Selectivity *cap) { int i; + int64 matched_count = 0; MCVList *mcv; Selectivity s = 0.0; RangeTblEntry *rte = root->simple_rte_array[rel->relid]; @@ -2133,22 +2134,24 @@ mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat, { *basesel += mcv->items[i].base_frequency; s += mcv->items[i].frequency; + matched_count++; } } /* - * When no MCV item matched and there is one equality clause per MCV - * dimension, cap the selectivity to the least common MCV frequency. The + * When there is one equality/IN clause per MCV dimension, cap the + * contribution of value combinations not found in the MCV. Each such * combination is not among the most common, so it can't be more frequent * than the least common tracked combination. */ - if (s == 0.0 && mcv->ndimensions == list_length(clauses)) + if (mcv->ndimensions == list_length(clauses)) { int64 cap_mult = mcv_cap_multiplier(clauses); + int64 non_mcv_mult = cap_mult - matched_count; - if (cap_mult > 0) + if (non_mcv_mult > 0) { - *cap = cap_mult * mcv->items[mcv->nitems - 1].frequency; + *cap = s + non_mcv_mult * mcv->items[mcv->nitems - 1].frequency; CLAMP_PROBABILITY(*cap); } } diff --git a/src/test/regress/expected/stats_ext.out b/src/test/regress/expected/stats_ext.out index 82ad9edb568..7ea244f7851 100644 --- a/src/test/regress/expected/stats_ext.out +++ b/src/test/regress/expected/stats_ext.out @@ -2969,7 +2969,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_cap WHERE a = 0 AND b = 0' SELECT * FROM check_estimated_rows('SELECT * FROM mcv_cap WHERE a = 0 AND b IN (0, 99)'); estimated | actual -----------+-------- - 5050 | 100 + 200 | 100 (1 row) -- no MCV match -- 2.43.0