a0942f441 added ExecCopySlotMinimalTupleExtra(), which accepts a parameter to specify the number of "extra" bytes that we want to allocate along with the MinimalTuple. That's now used in execGrouping.c to save some memory.
The same optimisation can be applied in nodeMemoize.c. MemoizeTuple has a field for the tuple being stored and 1 other field to point to the next tuple cached for this MemoizeEntry. Here we could use ExecCopySlotMinimalTupleExtra() to specify that we want a pointer's worth of extra bytes palloc'd for the MinimalTuple, and then store the pointer to the next tuple in those bytes. This saves 16 bytes per cached tuple. 24 bytes less because we don't palloc a MemoizeTuple (including the MemoryChunk's 8 bytes), and 8 bytes more for the ExecCopySlotMinimalTupleExtra bytes, a net saving of 16 bytes per tuple. Making Memoize use less memory is useful in cases where the cache would otherwise have to reload entries that were cached previously but were evicted due to reaching memory limits. A quick example: create table t1 (a int not null); create table t2 (a int not null); insert into t1 select x from generate_series(1,100000) x, generate_series(1,100); create index on t1 (a); insert into t2 select x%1000+1 from generate_series(1,1000000)x; analyze t1,t2; explain analyze select count(*) from t1 inner join t2 on t1.a=t2.a; Master: Memory Usage: 3583kB Patched: Memory Usage: 2801kB Really, the savings are double what's reported by EXPLAIN ANALYZE, as CACHE_TUPLE_BYTES doesn't account for any of the MemoryChunks that are consumed by palloc. We're now doing 1 fewer palloc per tuple due to the removal of the palloc_object(MemoizeTuple) code, so more like 30% less memory for this case. Patch attached. David
v1-0001-Reduce-memory-overheads-for-storing-a-Memoize-tup.patch
Description: Binary data
