From fbf1111d61564a69719f8f9034802c222abcd87a Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Mon, 17 Jun 2024 15:49:24 +0200 Subject: [PATCH v20240617 20/56] Cache the result of statext_determine_join_restrictions. It is firstly needed when choosing statext_find_matching_mcv and then it is needed when mcv_combine_extended, so caching the result to save some cycles. --- src/backend/statistics/extended_stats.c | 34 ++++++++++++++----- src/backend/statistics/mcv.c | 27 ++++++--------- .../statistics/extended_stats_internal.h | 2 ++ src/include/statistics/statistics.h | 3 +- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index 0e7dd7c9308..241c7d4ec35 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -2641,7 +2641,8 @@ make_build_data(Relation rel, StatExtEntry *stat, int numrows, HeapTuple *rows, /* * statext_find_matching_mcv - * Search for a MCV covering all the attributes and expressions. + * Search for a MCV covering all the attributes and expressions and set + * the conditions to calculate conditional probability. * * Picks the extended statistics object to estimate join clause. The statistics * object has to have a MCV, and we require it to match all the join conditions @@ -2668,7 +2669,8 @@ make_build_data(Relation rel, StatExtEntry *stat, int numrows, HeapTuple *rows, */ StatisticExtInfo * statext_find_matching_mcv(PlannerInfo *root, RelOptInfo *rel, - Bitmapset *attnums, List *exprs) + Bitmapset *attnums, List *exprs, + List **base_conditions) { ListCell *l; StatisticExtInfo *mcv = NULL; @@ -2693,6 +2695,7 @@ statext_find_matching_mcv(PlannerInfo *root, RelOptInfo *rel, if (!mcv) { mcv = stat; + *base_conditions = statext_determine_join_restrictions(root, rel, mcv); continue; } @@ -2750,8 +2753,13 @@ statext_find_matching_mcv(PlannerInfo *root, RelOptInfo *rel, if (list_length(conditions1) > list_length(conditions2)) { mcv = stat; + *base_conditions = conditions1; continue; } + else + { + *base_conditions = conditions2; + } /* * The statistics seem about equal, so just use the narrower one. @@ -2762,6 +2770,11 @@ statext_find_matching_mcv(PlannerInfo *root, RelOptInfo *rel, bms_num_members(stat->keys) + list_length(stat->exprs)) { mcv = stat; + *base_conditions = conditions1; + } + else + { + *base_conditions = conditions2; } } @@ -2776,7 +2789,7 @@ statext_find_matching_mcv(PlannerInfo *root, RelOptInfo *rel, * and covered by the extended statistics object. * * When using extended statistics to estimate joins, we can use conditions - * from base relations to calculate conditional probability + * from base relations to calculate conditional probability. * * P(join clauses | baserel restrictions) * @@ -3113,7 +3126,7 @@ statext_build_join_pairs(PlannerInfo *root, List *clauses, */ static RelOptInfo * extract_relation_info(PlannerInfo *root, JoinPairInfo *info, int index, - StatisticExtInfo **stat) + StatisticExtInfo **stat, List **base_conditions) { int relid; RelOptInfo *rel; @@ -3187,7 +3200,7 @@ extract_relation_info(PlannerInfo *root, JoinPairInfo *info, int index, } } - *stat = statext_find_matching_mcv(root, rel, attnums, exprs); + *stat = statext_find_matching_mcv(root, rel, attnums, exprs, base_conditions); return rel; } @@ -3305,11 +3318,14 @@ statext_clauselist_join_selectivity(PlannerInfo *root, List *clauses, StatisticExtInfo *stat1; StatisticExtInfo *stat2; + List *base_condition1 = NULL, + *base_condition2 = NULL; + /* extract info about the first relation */ - rel1 = extract_relation_info(root, &info[i], 0, &stat1); + rel1 = extract_relation_info(root, &info[i], 0, &stat1, &base_condition1); /* extract info about the second relation */ - rel2 = extract_relation_info(root, &info[i], 1, &stat2); + rel2 = extract_relation_info(root, &info[i], 1, &stat2, &base_condition2); /* * We can handle three basic cases: @@ -3332,7 +3348,9 @@ statext_clauselist_join_selectivity(PlannerInfo *root, List *clauses, */ if (stat1 && stat2) { - s *= mcv_combine_extended(root, rel1, rel2, stat1, stat2, info[i].clauses); + s *= mcv_combine_extended(root, rel1, rel2, stat1, stat2, + base_condition1, base_condition2, + info[i].clauses); } else if (stat1 && (list_length(info[i].clauses) == 1)) { diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c index 0cbe7821fcc..68a2cff1611 100644 --- a/src/backend/statistics/mcv.c +++ b/src/backend/statistics/mcv.c @@ -2208,6 +2208,7 @@ mcv_clause_selectivity_or(PlannerInfo *root, StatisticExtInfo *stat, Selectivity mcv_combine_extended(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, StatisticExtInfo *stat1, StatisticExtInfo *stat2, + List *base_cond1, List *base_cond2, List *clauses) { ListCell *lc; @@ -2219,12 +2220,10 @@ mcv_combine_extended(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, Selectivity s = 0; /* match bitmaps and selectivity for baserel conditions (if any) */ - List *exprs1 = NIL, - *exprs2 = NIL; - List *conditions1 = NIL, - *conditions2 = NIL; - bool *cmatches1 = NULL, - *cmatches2 = NULL; + List *exprs1 = NIL, + *exprs2 = NIL; + bool *cmatches1 = NULL, + *cmatches2 = NULL; double csel1 = 1.0, csel2 = 1.0; @@ -2264,28 +2263,24 @@ mcv_combine_extended(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, /* should only get here with MCV on both sides */ Assert(mcv1 && mcv2); - /* Determine which baserel clauses to use for conditional probability. */ - conditions1 = statext_determine_join_restrictions(root, rel1, stat1); - conditions2 = statext_determine_join_restrictions(root, rel2, stat2); - /* * Calculate match bitmaps for restrictions on either side of the join * (there may be none, in which case this will be NULL). */ - if (conditions1) + if (base_cond1) { - cmatches1 = mcv_get_match_bitmap(root, conditions1, + cmatches1 = mcv_get_match_bitmap(root, base_cond1, stat1->keys, stat1->exprs, mcv1, false); - csel1 = clauselist_selectivity(root, conditions1, rel1->relid, 0, NULL); + csel1 = clauselist_selectivity(root, base_cond1, rel1->relid, 0, NULL); } - if (conditions2) + if (base_cond2) { - cmatches2 = mcv_get_match_bitmap(root, conditions2, + cmatches2 = mcv_get_match_bitmap(root, base_cond2, stat2->keys, stat2->exprs, mcv2, false); - csel2 = clauselist_selectivity(root, conditions2, rel2->relid, 0, NULL); + csel2 = clauselist_selectivity(root, base_cond2, rel2->relid, 0, NULL); } /* diff --git a/src/include/statistics/extended_stats_internal.h b/src/include/statistics/extended_stats_internal.h index b1f30dfe2ee..1d16366f041 100644 --- a/src/include/statistics/extended_stats_internal.h +++ b/src/include/statistics/extended_stats_internal.h @@ -141,6 +141,8 @@ extern Selectivity mcv_combine_extended(PlannerInfo *root, RelOptInfo *rel2, StatisticExtInfo *stat1, StatisticExtInfo *stat2, + List *base_cond1, + List *base_cond2, List *clauses); extern List *statext_determine_join_restrictions(PlannerInfo *root, diff --git a/src/include/statistics/statistics.h b/src/include/statistics/statistics.h index 531feef85a4..d1368a05833 100644 --- a/src/include/statistics/statistics.h +++ b/src/include/statistics/statistics.h @@ -128,7 +128,8 @@ extern StatisticExtInfo *choose_best_statistics(List *stats, char requiredkind, extern HeapTuple statext_expressions_load(Oid stxoid, bool inh, int idx); extern StatisticExtInfo *statext_find_matching_mcv(PlannerInfo *root, RelOptInfo *rel, - Bitmapset *attnums, List *exprs); + Bitmapset *attnums, List *exprs, + List **base_conditions); extern bool statext_try_join_estimates(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo); -- 2.45.2