From 0588ee63aa2d8c5765d086991555cd9acdd4d86f Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Fri, 3 Apr 2020 19:52:16 -0700 Subject: [PATCH] Include chunk overhead in hash table entry size estimate. Don't try to be precise about it, just use a constant 16 bytes of chunk overhead. Being smarter would require knowing the memory context where the chunk will be allocated, which is not known by all callers. Discussion: https://postgr.es/m/20200325220936.il3ni2fj2j2b45y5@alap3.anarazel.de --- src/backend/executor/nodeAgg.c | 36 ++++++++++++++++++++++++++++------ src/include/executor/nodeAgg.h | 2 +- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 4c8c5cfc07..4e100e5755 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -297,6 +297,12 @@ /* minimum number of initial hash table buckets */ #define HASHAGG_MIN_BUCKETS 256 +/* + * Estimate chunk overhead as a constant 16 bytes. XXX: should this be + * improved? + */ +#define CHUNKHDRSZ 16 + /* * Track all tapes needed for a HashAgg that spills. We don't know the maximum * number of tapes needed at the start of the algorithm (because it can @@ -1639,14 +1645,32 @@ find_hash_columns(AggState *aggstate) * Estimate per-hash-table-entry overhead. */ Size -hash_agg_entry_size(int numAggs, Size tupleWidth, Size transitionSpace) +hash_agg_entry_size(int numTrans, Size tupleWidth, Size transitionSpace) { + Size tupleChunkSize; + Size pergroupChunkSize; + Size transitionChunkSize; + Size tupleSize = (MAXALIGN(SizeofMinimalTupleHeader) + + tupleWidth); + Size pergroupSize = numTrans * sizeof(AggStatePerGroupData); + + tupleChunkSize = CHUNKHDRSZ + tupleSize; + + if (pergroupSize > 0) + pergroupChunkSize = CHUNKHDRSZ + pergroupSize; + else + pergroupChunkSize = 0; + + if (transitionSpace > 0) + transitionChunkSize = CHUNKHDRSZ + transitionSpace; + else + transitionChunkSize = 0; + return - MAXALIGN(SizeofMinimalTupleHeader) + - MAXALIGN(tupleWidth) + - MAXALIGN(sizeof(TupleHashEntryData) + - numAggs * sizeof(AggStatePerGroupData)) + - transitionSpace; + sizeof(TupleHashEntryData) + + tupleChunkSize + + pergroupChunkSize + + transitionChunkSize; } /* diff --git a/src/include/executor/nodeAgg.h b/src/include/executor/nodeAgg.h index a5b8a004d1..c2b55728bf 100644 --- a/src/include/executor/nodeAgg.h +++ b/src/include/executor/nodeAgg.h @@ -314,7 +314,7 @@ extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags); extern void ExecEndAgg(AggState *node); extern void ExecReScanAgg(AggState *node); -extern Size hash_agg_entry_size(int numAggs, Size tupleWidth, +extern Size hash_agg_entry_size(int numTrans, Size tupleWidth, Size transitionSpace); extern void hash_agg_set_limits(double hashentrysize, uint64 input_groups, int used_bits, Size *mem_limit,