Skip to content

Commit 24e7aad

Browse files
author
Commitfest Bot
committed
[CF 5697] v11 - Add planner expectations for Memoize in EXPLAIN
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5697 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/CAApHDvq+uqf3MRFb+Ai3W1k3fMnrwWBLhzUAYj3_+MM8jK32fA@mail.gmail.com Author(s): Ilia Evdokimov
2 parents 71c0921 + 69922ca commit 24e7aad

File tree

7 files changed

+62
-12
lines changed

7 files changed

+62
-12
lines changed

src/backend/commands/explain.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3616,6 +3616,26 @@ show_memoize_info(MemoizeState *mstate, List *ancestors, ExplainState *es)
36163616
ExplainPropertyText("Cache Key", keystr.data, es);
36173617
ExplainPropertyText("Cache Mode", mstate->binary_mode ? "binary" : "logical", es);
36183618

3619+
if (es->costs)
3620+
{
3621+
if (es->format == EXPLAIN_FORMAT_TEXT)
3622+
{
3623+
ExplainIndentText(es);
3624+
appendStringInfo(es->str, "Estimates: capacity=%u distinct keys=%.0f lookups=%.0f hit percent=%.2f%%\n",
3625+
((Memoize *) plan)->est_entries,
3626+
((Memoize *) plan)->est_unique_keys,
3627+
((Memoize *) plan)->est_calls,
3628+
((Memoize *) plan)->est_hit_ratio * 100.0);
3629+
}
3630+
else
3631+
{
3632+
ExplainPropertyUInteger("Estimated Capacity", NULL, ((Memoize *) plan)->est_entries, es);
3633+
ExplainPropertyFloat("Estimated Distinct Lookup Keys", NULL, ((Memoize *) plan)->est_unique_keys, 0, es);
3634+
ExplainPropertyFloat("Estimated Lookups", NULL, ((Memoize *) plan)->est_calls, 0, es);
3635+
ExplainPropertyFloat("Estimated Hit Percent", NULL, ((Memoize *) plan)->est_hit_ratio * 100.0, 2, es);
3636+
}
3637+
}
3638+
36193639
pfree(keystr.data);
36203640

36213641
if (!es->analyze)

src/backend/optimizer/path/costsize.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2572,7 +2572,7 @@ cost_memoize_rescan(PlannerInfo *root, MemoizePath *mpath,
25722572
Cost input_startup_cost = mpath->subpath->startup_cost;
25732573
Cost input_total_cost = mpath->subpath->total_cost;
25742574
double tuples = mpath->subpath->rows;
2575-
double calls = mpath->calls;
2575+
double est_calls = mpath->est_calls;
25762576
int width = mpath->subpath->pathtarget->width;
25772577

25782578
double hash_mem_bytes;
@@ -2604,7 +2604,7 @@ cost_memoize_rescan(PlannerInfo *root, MemoizePath *mpath,
26042604
est_cache_entries = floor(hash_mem_bytes / est_entry_bytes);
26052605

26062606
/* estimate on the distinct number of parameter values */
2607-
ndistinct = estimate_num_groups(root, mpath->param_exprs, calls, NULL,
2607+
ndistinct = estimate_num_groups(root, mpath->param_exprs, est_calls, NULL,
26082608
&estinfo);
26092609

26102610
/*
@@ -2616,7 +2616,7 @@ cost_memoize_rescan(PlannerInfo *root, MemoizePath *mpath,
26162616
* certainly mean a MemoizePath will never survive add_path().
26172617
*/
26182618
if ((estinfo.flags & SELFLAG_USED_DEFAULT) != 0)
2619-
ndistinct = calls;
2619+
ndistinct = est_calls;
26202620

26212621
/*
26222622
* Since we've already estimated the maximum number of entries we can
@@ -2630,6 +2630,9 @@ cost_memoize_rescan(PlannerInfo *root, MemoizePath *mpath,
26302630
mpath->est_entries = Min(Min(ndistinct, est_cache_entries),
26312631
PG_UINT32_MAX);
26322632

2633+
/* Remember the ndistinct estimate for EXPLAIN */
2634+
mpath->est_unique_keys = ndistinct;
2635+
26332636
/*
26342637
* When the number of distinct parameter values is above the amount we can
26352638
* store in the cache, then we'll have to evict some entries from the
@@ -2644,9 +2647,12 @@ cost_memoize_rescan(PlannerInfo *root, MemoizePath *mpath,
26442647
* must look at how many scans are estimated in total for this node and
26452648
* how many of those scans we expect to get a cache hit.
26462649
*/
2647-
hit_ratio = ((calls - ndistinct) / calls) *
2650+
hit_ratio = ((est_calls - ndistinct) / est_calls) *
26482651
(est_cache_entries / Max(ndistinct, est_cache_entries));
26492652

2653+
/* Remember the hit ratio estimate for EXPLAIN */
2654+
mpath->est_hit_ratio = hit_ratio;
2655+
26502656
Assert(hit_ratio >= 0 && hit_ratio <= 1.0);
26512657

26522658
/*

src/backend/optimizer/plan/createplan.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,9 @@ static Material *make_material(Plan *lefttree);
284284
static Memoize *make_memoize(Plan *lefttree, Oid *hashoperators,
285285
Oid *collations, List *param_exprs,
286286
bool singlerow, bool binary_mode,
287-
uint32 est_entries, Bitmapset *keyparamids);
287+
uint32 est_entries, Bitmapset *keyparamids,
288+
double est_calls, double est_unique_keys,
289+
double est_hit_ratio);
288290
static WindowAgg *make_windowagg(List *tlist, WindowClause *wc,
289291
int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations,
290292
int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations,
@@ -1753,7 +1755,8 @@ create_memoize_plan(PlannerInfo *root, MemoizePath *best_path, int flags)
17531755

17541756
plan = make_memoize(subplan, operators, collations, param_exprs,
17551757
best_path->singlerow, best_path->binary_mode,
1756-
best_path->est_entries, keyparamids);
1758+
best_path->est_entries, keyparamids, best_path->est_calls,
1759+
best_path->est_unique_keys, best_path->est_hit_ratio);
17571760

17581761
copy_generic_path_info(&plan->plan, (Path *) best_path);
17591762

@@ -6749,7 +6752,8 @@ materialize_finished_plan(Plan *subplan)
67496752
static Memoize *
67506753
make_memoize(Plan *lefttree, Oid *hashoperators, Oid *collations,
67516754
List *param_exprs, bool singlerow, bool binary_mode,
6752-
uint32 est_entries, Bitmapset *keyparamids)
6755+
uint32 est_entries, Bitmapset *keyparamids, double est_calls,
6756+
double est_unique_keys, double est_hit_ratio)
67536757
{
67546758
Memoize *node = makeNode(Memoize);
67556759
Plan *plan = &node->plan;
@@ -6767,6 +6771,9 @@ make_memoize(Plan *lefttree, Oid *hashoperators, Oid *collations,
67676771
node->binary_mode = binary_mode;
67686772
node->est_entries = est_entries;
67696773
node->keyparamids = keyparamids;
6774+
node->est_calls = est_calls;
6775+
node->est_unique_keys = est_unique_keys;
6776+
node->est_hit_ratio = est_hit_ratio;
67706777

67716778
return node;
67726779
}

src/backend/optimizer/util/pathnode.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,7 +1689,7 @@ create_material_path(RelOptInfo *rel, Path *subpath)
16891689
MemoizePath *
16901690
create_memoize_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
16911691
List *param_exprs, List *hash_operators,
1692-
bool singlerow, bool binary_mode, double calls)
1692+
bool singlerow, bool binary_mode, double est_calls)
16931693
{
16941694
MemoizePath *pathnode = makeNode(MemoizePath);
16951695

@@ -1710,7 +1710,6 @@ create_memoize_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
17101710
pathnode->param_exprs = param_exprs;
17111711
pathnode->singlerow = singlerow;
17121712
pathnode->binary_mode = binary_mode;
1713-
pathnode->calls = clamp_row_est(calls);
17141713

17151714
/*
17161715
* For now we set est_entries to 0. cost_memoize_rescan() does all the
@@ -1720,6 +1719,12 @@ create_memoize_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath,
17201719
*/
17211720
pathnode->est_entries = 0;
17221721

1722+
pathnode->est_calls = clamp_row_est(est_calls);
1723+
1724+
/* These will also be set later in cost_memoize_rescan() */
1725+
pathnode->est_unique_keys = 0;
1726+
pathnode->est_hit_ratio = 0;
1727+
17231728
/* we should not generate this path type when enable_memoize=false */
17241729
Assert(enable_memoize);
17251730
pathnode->path.disabled_nodes = subpath->disabled_nodes;
@@ -4259,7 +4264,7 @@ reparameterize_path(PlannerInfo *root, Path *path,
42594264
mpath->hash_operators,
42604265
mpath->singlerow,
42614266
mpath->binary_mode,
4262-
mpath->calls);
4267+
mpath->est_calls);
42634268
}
42644269
default:
42654270
break;

src/include/nodes/pathnodes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2133,10 +2133,12 @@ typedef struct MemoizePath
21332133
* complete after caching the first record. */
21342134
bool binary_mode; /* true when cache key should be compared bit
21352135
* by bit, false when using hash equality ops */
2136-
Cardinality calls; /* expected number of rescans */
21372136
uint32 est_entries; /* The maximum number of entries that the
21382137
* planner expects will fit in the cache, or 0
21392138
* if unknown */
2139+
Cardinality est_calls; /* expected number of rescans */
2140+
Cardinality est_unique_keys; /* estimated unique keys, for EXPLAIN */
2141+
double est_hit_ratio; /* estimated cache hit ratio, for EXPLAIN */
21402142
} MemoizePath;
21412143

21422144
/*

src/include/nodes/plannodes.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,16 @@ typedef struct Memoize
10731073

10741074
/* paramids from param_exprs */
10751075
Bitmapset *keyparamids;
1076+
1077+
/* Estimated number of rescans, for EXPLAIN */
1078+
Cardinality est_calls;
1079+
1080+
/* Estimated number of distinct lookup keys, for EXPLAIN */
1081+
Cardinality est_unique_keys;
1082+
1083+
/* Estimated cache hit ratio, for EXPLAIN */
1084+
double est_hit_ratio;
1085+
10761086
} Memoize;
10771087

10781088
/* ----------------

src/include/optimizer/pathnode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ extern MemoizePath *create_memoize_path(PlannerInfo *root,
9090
List *hash_operators,
9191
bool singlerow,
9292
bool binary_mode,
93-
double calls);
93+
double est_calls);
9494
extern UniquePath *create_unique_path(PlannerInfo *root, RelOptInfo *rel,
9595
Path *subpath, SpecialJoinInfo *sjinfo);
9696
extern GatherPath *create_gather_path(PlannerInfo *root,

0 commit comments

Comments
 (0)