Thread: Index padding optimization

Index padding optimization

From
ITAGAKI Takahiro
Date:
Attached is a patch that removes undesired paddings from b-tree indexes.

The tuples of b-tree index consist of BTItemData and index keys. BTItemData
should be placed only 2 byte alignment, so if the alignment of keys are less
than MAXIMUM_ALIGNOF, we can place them with their minimum alignment instead
of MAXALIGN.


I tested this patch with pgbench on the machine where MAXIMUM_ALIGNOF is 8.
It saved 20% of index file sizes, because accounts_pkey is btree index on
an integer (4 bytes), so the size for one tuple changed as follows:
 - original : 20 bytes = ItemIdData(4) + BTItemData(8) + key(4) + padding(4)
 - patched  : 16 bytes = ItemIdData(4) + BTItemData(8) + key(4)

./pgbench -i -s 100
# select relpages from pg_class where relname='accounts_pkey';
- original : relpages = 27422
- patched  : relpages = 21899

---
ITAGAKI Takahiro
NTT Cyber Space Laboratories

Attachment

Re: Index padding optimization

From
Tom Lane
Date:
ITAGAKI Takahiro <itagaki.takahiro@lab.ntt.co.jp> writes:
> Attached is a patch that removes undesired paddings from b-tree indexes.

This seems extremely invasive for a relatively small gain :-(
The example you cite of an int4 index on a MAXALIGN-8 machine is
by far the best case, and in many cases there wouldn't be anything
bought by the extra complexity.

Aside from the code uglification, I'm concerned about the performance
implications of, for example, changing PageAddItem so that it has to
cope with non-compile-time-constant alignment calculations.  That adds
overhead for a lot of places that have nothing to do with btrees.

I'm also fairly sure that you've broken xlog recovery for btrees,
eg, btree_xlog_newroot has no way to set up the btpo_align field.
(Personally I'd try to get rid of btpo_align, not fix xlog to
maintain it.)

You could simplify some things by continuing to use MAXALIGN in places
that are just doing freespace calculations and not actually placing a
tuple on a page.  This would waste at worst 4 bytes per page so it does
not seem worthwhile to be more precise.

Another thing that would be interesting to think about is adopting the
convention that lp_len should always be the length with alignment
padding included.  This'd eliminate the need to do repetitive alignment
calculations in some places like PageRepairFragmentation and
PageIndexMultiDelete, and thus avoid the need to pass alignment
information to them at all.  I can't at the moment see a reason why
we need to remember the tuple length to exact byte precision.
(This would however require that all tuples on a page have the *same*
alignment requirement, else compaction might place some at unsuitable
locations.  The code you put in index_form_tuple to make the alignment
variable depending on presence of nulls does not seem like a good idea
to me in any case.)

I'd also advise not making unnecessary changes in function names;
adding Aligned to those function names isn't doing anything to improve
readability of the code.

            regards, tom lane

Re: Index padding optimization

From
ITAGAKI Takahiro
Date:
Tom Lane <tgl@sss.pgh.pa.us> wrote:

> This seems extremely invasive for a relatively small gain :-(
> The example you cite of an int4 index on a MAXALIGN-8 machine is
> by far the best case, and in many cases there wouldn't be anything
> bought by the extra complexity.

I also think that it has small advantage without another compression method.
But if we tries to compress index keys using prefix compression or so,
we might need to put tuples with no/small alignment.

I would like to propose it again when I find another method which will work
well with this patch.

---
ITAGAKI Takahiro
NTT Cyber Space Laboratories