1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

BRIN minmax-multi indexes

Adds BRIN opclasses similar to the existing minmax, except that instead
of summarizing the page range into a single [min,max] range, the summary
consists of multiple ranges and/or points, allowing gaps. This allows
more efficient handling of data with poor correlation to physical
location within the table and/or outlier values, for which the regular
minmax opclassed tend to work poorly.

It's possible to specify the number of values kept for each page range,
either as a single point or an interval boundary.

  CREATE TABLE t (a int);
  CREATE INDEX ON t
   USING brin (a int4_minmax_multi_ops(values_per_range=16));

When building the summary, the values are combined into intervals with
the goal to minimize the "covering" (sum of interval lengths), using a
support procedure computing distance between two values.

Bump catversion, due to various catalog changes.

Author: Tomas Vondra <tomas.vondra@postgresql.org>
Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
Reviewed-by: Sokolov Yura <y.sokolov@postgrespro.ru>
Reviewed-by: John Naylor <john.naylor@enterprisedb.com>
Discussion: https://postgr.es/m/c1138ead-7668-f0e1-0638-c3be3237e812@2ndquadrant.com
Discussion: https://postgr.es/m/5d78b774-7e9c-c94e-12cf-fef51cc89b1a%402ndquadrant.com
This commit is contained in:
Tomas Vondra
2021-03-26 13:54:29 +01:00
parent 77b88cd1bb
commit ab596105b5
19 changed files with 5286 additions and 26 deletions

View File

@@ -17,6 +17,7 @@ OBJS = \
brin_bloom.o \
brin_inclusion.o \
brin_minmax.o \
brin_minmax_multi.o \
brin_pageops.o \
brin_revmap.o \
brin_tuple.o \

File diff suppressed because it is too large Load Diff

View File

@@ -159,6 +159,14 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple,
if (tuple->bt_columns[keyno].bv_hasnulls)
anynulls = true;
/* If needed, serialize the values before forming the on-disk tuple. */
if (tuple->bt_columns[keyno].bv_serialize)
{
tuple->bt_columns[keyno].bv_serialize(brdesc,
tuple->bt_columns[keyno].bv_mem_value,
tuple->bt_columns[keyno].bv_values);
}
/*
* Now obtain the values of each stored datum. Note that some values
* might be toasted, and we cannot rely on the original heap values
@@ -512,6 +520,11 @@ brin_memtuple_initialize(BrinMemTuple *dtuple, BrinDesc *brdesc)
dtuple->bt_columns[i].bv_allnulls = true;
dtuple->bt_columns[i].bv_hasnulls = false;
dtuple->bt_columns[i].bv_values = (Datum *) currdatum;
dtuple->bt_columns[i].bv_mem_value = PointerGetDatum(NULL);
dtuple->bt_columns[i].bv_serialize = NULL;
dtuple->bt_columns[i].bv_context = dtuple->bt_context;
currdatum += sizeof(Datum) * brdesc->bd_info[i]->oi_nstored;
}
@@ -591,6 +604,10 @@ brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple, BrinMemTuple *dMemtuple)
dtup->bt_columns[keyno].bv_hasnulls = hasnulls[keyno];
dtup->bt_columns[keyno].bv_allnulls = false;
dtup->bt_columns[keyno].bv_mem_value = PointerGetDatum(NULL);
dtup->bt_columns[keyno].bv_serialize = NULL;
dtup->bt_columns[keyno].bv_context = dtup->bt_context;
}
MemoryContextSwitchTo(oldcxt);