Re: Reducing relcache memory usage: deduping index shapes

From: David Geier <geidav(dot)pg(at)gmail(dot)com>
To: Matthias van de Meent <boekewurm+postgres(at)gmail(dot)com>
Cc: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Andres Freund <andres(at)anarazel(dot)de>
Subject: Re: Reducing relcache memory usage: deduping index shapes
Date: 2026-09-03 16:02:23
Message-ID: 629a73a1-8090-43e5-b762-ed586f3683e0@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

>>> I've considered allocating Relations in a slab context to avoid aset's
>>> alignment overhead, but never got far enough with a prototype to get
>>> it to pass all tests.
>>
>> With the other optimizations from [1] we should be able to get below 256
>> bytes. If you want I can give this a try.
>
> Back-of-the-envelope calculation: Currently, RelationData is 488
> bytes, of which 50 wasted on alignment (so, 48 bytes recoverable). If
> we somehow get the index and table fields to not be used at the same
> time, we'd gain another 128 bytes (because the larger of the two must
> remain). This leaves us with 312 bytes, which is still 56 bytes over
> the target, and I don't think we can trivially find 7 pointers' worth
> of fields to remove.
>
> But, feel free to try.

I've managed to crunch sizeof(RelationData) down to 256 bytes and
there's some more room for improvement, see below. Attached is the patch
set. It passes tests.

I had to move RelationData into a new header because the script that
extracts node metadata doesn't like the anonymous unions.

With the patch, GetMemoryChunkSpace(rel) == 264 because the allocation
falls into the 256 bytes size class and additionally has an 8 byte
header. Previously it was 520 bytes.

We could additionally:

1) Change all the arrays of length nkeys to a single array of structs.
That would save a bunch of pointers in the index union elg. It's not
clear though if that might regress performance somewhere because of
cache locality but would be worth a try.

2) Put rules and trigger related members into separately allocated
structured referenced by a single pointer. These members are rarely used
and shouldn't be performance critical.

3) Pack booleans into bitfield.

That might save another 24 or more bytes (depends on the biggest union
leg and padding at the end of the struct). But for the PoC I didn't do that.

--
David Geier

Attachment Content-Type Size
v1-0008-Add-static-assert-for-size.patch text/x-patch 754 bytes
v1-0007-Remove-rd_index.patch text/x-patch 52.5 KB
v1-0006-Remove-rd_fkeyvalid.patch text/x-patch 4.1 KB
v1-0005-Move-out-partition-members.patch text/x-patch 20.6 KB
v1-0004-Remove-rd_lockinfo.patch text/x-patch 20.4 KB
v1-0003-Packing-RelationData.patch text/x-patch 7.6 KB
v1-0002-Use-union.patch text/x-patch 22.4 KB
v1-0001-Move-RelationData-to-new-include.patch text/x-patch 21.5 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Paul A Jungwirth 2026-09-03 16:08:10 Re: FOR PORTION OF silently ignored on views with DO INSTEAD rules
Previous Message Ayoub Kazar 2026-09-03 16:01:15 Re: Speed up COPY TO text/CSV parsing using SIMD