Include chunk overhead in hash table entry size estimate.
authorJeff Davis <[email protected]>
Sat, 4 Apr 2020 02:52:16 +0000 (19:52 -0700)
committerJeff Davis <[email protected]>
Sat, 4 Apr 2020 03:07:58 +0000 (20:07 -0700)
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[email protected]

src/backend/executor/nodeAgg.c
src/include/executor/nodeAgg.h

index 4c8c5cfc07af05c0497b2726e663fe420620af94..4e100e5755f1c562b2f90c3aa399794da5a9788e 100644 (file)
 /* 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;
 }
 
 /*
index a5b8a004d1e55cae279b2bd185e5d160eba0568d..c2b55728bfa2c6fd242d13413f76f8f5f8b1d4d9 100644 (file)
@@ -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,