diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index d2a2479822..c535d63883 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -3177,6 +3177,11 @@ show_memoize_info(MemoizeState *mstate, List *ancestors, ExplainState *es) ExplainPropertyInteger("Cache Evictions", NULL, mstate->stats.cache_evictions, es); ExplainPropertyInteger("Cache Overflows", NULL, mstate->stats.cache_overflows, es); ExplainPropertyInteger("Peak Memory Usage", "kB", memPeakKb, es); + ExplainPropertyInteger("Maximum Hash Buckets", NULL, + mstate->stats.hashsize_max, es); + ExplainPropertyInteger("Original Hash Buckets", NULL, + mstate->stats.hashsize_orig, es); + } else { @@ -3188,6 +3193,14 @@ show_memoize_info(MemoizeState *mstate, List *ancestors, ExplainState *es) mstate->stats.cache_evictions, mstate->stats.cache_overflows, memPeakKb); + ExplainIndentText(es); + if (mstate->stats.hashsize_max != mstate->stats.hashsize_orig) + appendStringInfo(es->str, "Hash Buckets: %u (originally %u)\n", + mstate->stats.hashsize_max, + mstate->stats.hashsize_orig); + else + appendStringInfo(es->str, "Hash Buckets: %u\n", + mstate->stats.hashsize_max); } } @@ -3227,6 +3240,14 @@ show_memoize_info(MemoizeState *mstate, List *ancestors, ExplainState *es) si->cache_hits, si->cache_misses, si->cache_evictions, si->cache_overflows, memPeakKb); + ExplainIndentText(es); + if (si->hashsize_max != si->hashsize_orig) + appendStringInfo(es->str, "Hash Buckets: %u (originally %u)\n", + si->hashsize_max, + si->hashsize_orig); + else + appendStringInfo(es->str, "Hash Buckets: %u\n", + si->hashsize_max); } else { @@ -3240,6 +3261,11 @@ show_memoize_info(MemoizeState *mstate, List *ancestors, ExplainState *es) si->cache_overflows, es); ExplainPropertyInteger("Peak Memory Usage", "kB", memPeakKb, es); + ExplainPropertyInteger("Maximum Hash Buckets", NULL, + si->hashsize_max, es); + ExplainPropertyInteger("Original Hash Buckets", NULL, + si->hashsize_orig, es); + } if (es->workers_state) diff --git a/src/backend/executor/nodeMemoize.c b/src/backend/executor/nodeMemoize.c index 23441e33ca..e2a17a615f 100644 --- a/src/backend/executor/nodeMemoize.c +++ b/src/backend/executor/nodeMemoize.c @@ -270,6 +270,10 @@ build_hash_table(MemoizeState *mstate, uint32 size) /* memoize_create will convert the size to a power of 2 */ mstate->hashtable = memoize_create(mstate->tableContext, size, mstate); + + /* Record the initial size of the hash table */ + if (mstate->stats.hashsize_orig == 0) + mstate->stats.hashsize_orig = mstate->hashtable->size; } /* @@ -527,6 +531,10 @@ cache_lookup(MemoizeState *mstate, bool *found) /* Update the total cache memory utilization */ mstate->mem_used += EMPTY_ENTRY_MEMORY_BYTES(entry); + /* Record the maximum size of the hash table */ + mstate->stats.hashsize_max = Max(mstate->stats.hashsize_max, + mstate->hashtable->size); + /* Initialize this entry */ entry->complete = false; entry->tuplehead = NULL; diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 94b191f8ae..1e7012d6e8 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -2109,6 +2109,8 @@ typedef struct MemoizeInstrumentation * able to free enough space to store the * current scan's tuples. */ uint64 mem_peak; /* peak memory usage in bytes */ + uint32 hashsize_orig; /* Original hash bucket count */ + uint32 hashsize_max; /* Maximum hash table bucket count */ } MemoizeInstrumentation; /* ----------------