From 4b61e5ae514f5e5bc430bcf1132597ba4ecd202b Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Tue, 31 Dec 2019 18:49:41 -0600 Subject: [PATCH v1 2/2] explain analyze to show stats from (hash) aggregate.. ..as suggested by Jeff Janes --- src/backend/commands/explain.c | 41 +++++++++++++++++++++++++++++-------- src/backend/executor/execGrouping.c | 10 +++++++++ src/include/nodes/execnodes.h | 27 ++++++++++++------------ 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 11b5857..9493e7d 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -18,6 +18,7 @@ #include "commands/createas.h" #include "commands/defrem.h" #include "commands/prepare.h" +#include "executor/nodeAgg.h" #include "executor/nodeHash.h" #include "foreign/fdwapi.h" #include "jit/jit.h" @@ -84,6 +85,7 @@ static void show_sort_keys(SortState *sortstate, List *ancestors, ExplainState *es); static void show_merge_append_keys(MergeAppendState *mstate, List *ancestors, ExplainState *es); +static void show_agg_info(AggState *astate, ExplainState *es); static void show_agg_keys(AggState *astate, List *ancestors, ExplainState *es); static void show_grouping_sets(PlanState *planstate, Agg *agg, @@ -103,7 +105,7 @@ static void show_sortorder_options(StringInfo buf, Node *sortexpr, static void show_tablesample(TableSampleClause *tsc, PlanState *planstate, List *ancestors, ExplainState *es); static void show_sort_info(SortState *sortstate, ExplainState *es); -static void show_hinstrument(ExplainState *es, HashInstrumentation *h); +static void show_hinstrument(ExplainState *es, HashInstrumentation *h, bool showbatch); static void show_hash_info(HashState *hashstate, ExplainState *es); static void show_tidbitmap_info(BitmapHeapScanState *planstate, ExplainState *es); @@ -1889,6 +1891,8 @@ ExplainNode(PlanState *planstate, List *ancestors, if (plan->qual) show_instrumentation_count("Rows Removed by Filter", 1, planstate, es); + show_agg_info(castNode(AggState, planstate), es); + break; case T_Group: show_group_keys(castNode(GroupState, planstate), ancestors, es); @@ -2072,6 +2076,21 @@ ExplainNode(PlanState *planstate, List *ancestors, } /* + * Show instrumentation info for an Agg node. + */ +static void +show_agg_info(AggState *astate, ExplainState *es) +{ + // perhash->aggnode->numGroups; memctx; AggState-> + + for (int i=0; inum_hashes; ++i) { + HashInstrumentation *hinstrument = &astate->perhash->hashtable->hinstrument; +// fprintf(stderr, "memallocated %lu\n", astate->hashcontext->ecxt_per_query_memory->mem_allocated); + show_hinstrument(es, hinstrument, false); + } +} + +/* * Show the targetlist of a plan node */ static void @@ -2714,14 +2733,14 @@ show_hash_info(HashState *hashstate, ExplainState *es) } } - show_hinstrument(es, &hinstrument); + show_hinstrument(es, &hinstrument, true); } /* * Show hash bucket stats and (optionally) memory. */ static void -show_hinstrument(ExplainState *es, HashInstrumentation *h) +show_hinstrument(ExplainState *es, HashInstrumentation *h, bool showbatch) { long spacePeakKb = (h->space_peak + 1023) / 1024; @@ -2755,9 +2774,12 @@ show_hinstrument(ExplainState *es, HashInstrumentation *h) h->nbuckets_original != h->nbuckets) { ExplainIndentText(es); appendStringInfo(es->str, - "Buckets: %d (originally %d) Batches: %d (originally %d)", + "Buckets: %d (originally %d)", h->nbuckets, - h->nbuckets_original, + h->nbuckets_original); + if (showbatch) + appendStringInfo(es->str, + " Batches: %d (originally %d)", h->nbatch, h->nbatch_original); } @@ -2765,9 +2787,12 @@ show_hinstrument(ExplainState *es, HashInstrumentation *h) { ExplainIndentText(es); appendStringInfo(es->str, - "Buckets: %d Batches: %d", - h->nbuckets, - h->nbatch); + "Buckets: %d", + h->nbuckets); + if (showbatch) + appendStringInfo(es->str, + " Batches: %d", + h->nbatch); } if (es->verbose && es->analyze) diff --git a/src/backend/executor/execGrouping.c b/src/backend/executor/execGrouping.c index 3603c58..cf0fe3c 100644 --- a/src/backend/executor/execGrouping.c +++ b/src/backend/executor/execGrouping.c @@ -203,6 +203,11 @@ BuildTupleHashTableExt(PlanState *parent, hashtable->hash_iv = 0; hashtable->hashtab = tuplehash_create(metacxt, nbuckets, hashtable); + hashtable->hinstrument.nbuckets_original = nbuckets; + hashtable->hinstrument.nbuckets = nbuckets; + hashtable->hinstrument.space_peak = entrysize * hashtable->hashtab->size; + hashtable->hinstrument.nbatch_original = 1; /* Unused */ + hashtable->hinstrument.nbatch = 1; /* Unused */ /* * We copy the input tuple descriptor just for safety --- we assume all @@ -328,6 +333,11 @@ LookupTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot, { /* created new entry */ *isnew = true; + /* maybe grew ? XXX: need to call max() here ? */ + hashtable->hinstrument.nbuckets = hashtable->hashtab->size; + hashtable->hinstrument.space_peak = sizeof(TupleHashEntryData) * hashtable->hashtab->size + + sizeof(MinimalTuple) * hashtable->hashtab->size; // members ? + /* zero caller data */ entry->additional = NULL; MemoryContextSwitchTo(hashtable->tablecxt); diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 1f6f5bb..913416f 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -671,6 +671,19 @@ typedef struct ExecAuxRowMark typedef struct TupleHashEntryData *TupleHashEntry; typedef struct TupleHashTableData *TupleHashTable; +/* ---------------- + * Values displayed by EXPLAIN ANALYZE + * ---------------- + */ +typedef struct HashInstrumentation +{ + int nbuckets; /* number of buckets at end of execution */ + int nbuckets_original; /* planned number of buckets */ + int nbatch; /* number of batches at end of execution */ + int nbatch_original; /* planned number of batches */ + size_t space_peak; /* peak memory usage in bytes */ +} HashInstrumentation; + typedef struct TupleHashEntryData { MinimalTuple firstTuple; /* copy of first tuple in this group */ @@ -705,6 +718,7 @@ typedef struct TupleHashTableData ExprState *cur_eq_func; /* comparator for input vs. table */ uint32 hash_iv; /* hash-function IV */ ExprContext *exprcontext; /* expression context */ + HashInstrumentation hinstrument; /* instrumentation for EXPLAIN */ } TupleHashTableData; typedef tuplehash_iterator TupleHashIterator; @@ -2243,19 +2257,6 @@ typedef struct GatherMergeState } GatherMergeState; /* ---------------- - * Values displayed by EXPLAIN ANALYZE - * ---------------- - */ -typedef struct HashInstrumentation -{ - int nbuckets; /* number of buckets at end of execution */ - int nbuckets_original; /* planned number of buckets */ - int nbatch; /* number of batches at end of execution */ - int nbatch_original; /* planned number of batches */ - size_t space_peak; /* peak memory usage in bytes */ -} HashInstrumentation; - -/* ---------------- * Shared memory container for per-worker hash information * ---------------- */ -- 2.7.4