Re: Poor memory context performance in large hash joins
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: Jeff Janes <jeff.janes@gmail.com>
Cc: pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2017-02-24T23:04:18Z
Lists: pgsql-hackers
Attachments
- doubly-linked-block-list.patch (text/x-diff) patch
Jeff Janes <jeff.janes@gmail.com> writes: > On Fri, Feb 24, 2017 at 10:59 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> Uh, what? In a doubly-linked list, you can remove an element in O(1) >> time, you don't need any searching. > Currently it is walking the chain to identify which block holds the chunk > in the first place, not just to get the pointer to the previous block. But > I see that that could be fixed by pointer arithmetic once there is a reason > to fix it. Which there isn't a reason to as long as you need to walk the > chain to get the prev pointer anyway. Like this:? > targetblock = (AllocBlock) (((char*)chunk) - ALLOC_BLOCKHDRSZ); Right. We're just turning around the existing address calculation. It'd be a good idea to provide some cross-check that we found a sane-looking block header, but that's not that hard --- we know what ought to be in aset, freeptr, and endptr for a single-chunk block's header, and that seems like enough of a crosscheck to me. Concretely, something like the attached. This passes regression tests but I've not pushed on it any harder than that. One argument against this is that it adds some nonzero amount of overhead to block management; but considering that we are calling malloc or realloc or free alongside any one of these manipulations, that overhead should be pretty negligible. I'm a bit more worried about increasing the alloc block header size by 8 bytes, but that would only really matter with a very small allocChunkLimit. regards, tom lane
Commits
-
Use doubly-linked block lists in aset.c to reduce large-chunk overhead.
- ff97741bc810 10.0 landed
- e0a6ed8a2525 9.6.3 landed
- 8dd5c4171fb2 9.4.12 landed
- 50a9d714ad0d 9.5.7 landed