Skip to content

Commit b32000e

Browse files
committed
Som improve page split in multicolumn GiST index.
If user picksplit on n-th column generate equals left and right unions then it calls picksplit on n+1-th column.
1 parent 0a6fde5 commit b32000e

File tree

3 files changed

+57
-42
lines changed

3 files changed

+57
-42
lines changed

src/backend/access/gist/gist.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.137 2006/05/24 11:01:39 teodor Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.138 2006/05/29 12:50:06 teodor Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1033,7 +1033,13 @@ gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *gist
10331033
/*
10341034
* all keys are not-null
10351035
*/
1036-
gistUserPicksplit(r, entryvec, attno, v, itup, len, giststate);
1036+
if ( gistUserPicksplit(r, entryvec, attno, v, itup, len, giststate) && attno+1 != r->rd_att->natts )
1037+
/*
1038+
* Splitting on attno column is not optimized: unions of left and right
1039+
* page are the same, we will try to split page by
1040+
* following columns
1041+
*/
1042+
gistSplitByKey(r, page, itup, len, giststate, v, entryvec, attno+1);
10371043
}
10381044
}
10391045

src/backend/access/gist/gistutil.c

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.14 2006/05/24 11:01:39 teodor Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.15 2006/05/29 12:50:06 teodor Exp $
1212
*-------------------------------------------------------------------------
1313
*/
1414
#include "postgres.h"
@@ -262,6 +262,16 @@ gistMakeUnionKey( GISTSTATE *giststate, int attno,
262262
}
263263
}
264264

265+
static bool
266+
gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b) {
267+
bool result;
268+
269+
FunctionCall3(&giststate->equalFn[attno],
270+
a, b,
271+
PointerGetDatum(&result));
272+
return result;
273+
}
274+
265275
/*
266276
* Forms union of oldtup and addtup, if union == oldtup then return NULL
267277
*/
@@ -300,19 +310,8 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
300310
continue;
301311

302312
if ( !addisnull[i] ) {
303-
if ( oldisnull[i] )
313+
if ( oldisnull[i] || gistKeyIsEQ(giststate, i, oldentries[i].key, attrS[i])==false )
304314
neednew = true;
305-
else {
306-
bool result;
307-
308-
FunctionCall3(&giststate->equalFn[i],
309-
oldentries[i].key,
310-
attrS[i],
311-
PointerGetDatum(&result));
312-
313-
if (!result)
314-
neednew = true;
315-
}
316315
}
317316
}
318317

@@ -395,7 +394,6 @@ gistfindgroup(GISTSTATE *giststate, GISTENTRY *valvec, GIST_SPLITVEC *spl, int a
395394
{
396395
int j;
397396
int len;
398-
bool result;
399397

400398
if (spl->spl_idgrp[spl->spl_left[i]])
401399
continue;
@@ -405,11 +403,7 @@ gistfindgroup(GISTSTATE *giststate, GISTENTRY *valvec, GIST_SPLITVEC *spl, int a
405403
{
406404
if (spl->spl_idgrp[spl->spl_right[j]])
407405
continue;
408-
FunctionCall3(&giststate->equalFn[attno],
409-
valvec[spl->spl_left[i]].key,
410-
valvec[spl->spl_right[j]].key,
411-
PointerGetDatum(&result));
412-
if (result)
406+
if (gistKeyIsEQ(giststate, attno, valvec[spl->spl_left[i]].key, valvec[spl->spl_right[j]].key))
413407
{
414408
spl->spl_idgrp[spl->spl_right[j]] = curid;
415409
len++;
@@ -425,11 +419,7 @@ gistfindgroup(GISTSTATE *giststate, GISTENTRY *valvec, GIST_SPLITVEC *spl, int a
425419
{
426420
if (spl->spl_idgrp[spl->spl_left[j]])
427421
continue;
428-
FunctionCall3(&giststate->equalFn[attno],
429-
valvec[spl->spl_left[i]].key,
430-
valvec[spl->spl_left[j]].key,
431-
PointerGetDatum(&result));
432-
if (result)
422+
if (gistKeyIsEQ(giststate, attno, valvec[spl->spl_left[i]].key, valvec[spl->spl_left[j]].key))
433423
{
434424
spl->spl_idgrp[spl->spl_left[j]] = curid;
435425
len++;
@@ -758,7 +748,14 @@ gistpenalty(GISTSTATE *giststate, int attno,
758748
return penalty;
759749
}
760750

761-
void
751+
/*
752+
* Calls user picksplit method for attno columns to split vector to
753+
* two vectors. May use attno+n columns data to
754+
* get better split.
755+
* Returns TRUE if left and right unions of attno columns are the same,
756+
* so caller may find better split
757+
*/
758+
bool
762759
gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GIST_SPLITVEC *v,
763760
IndexTuple *itup, int len, GISTSTATE *giststate)
764761
{
@@ -787,24 +784,36 @@ gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GIST_SPLITVE
787784
*/
788785
if (giststate->tupdesc->natts > 1 && attno+1 != giststate->tupdesc->natts)
789786
{
790-
int MaxGrpId;
787+
if ( gistKeyIsEQ(giststate, attno, v->spl_ldatum, v->spl_rdatum) ) {
788+
/*
789+
* Left and right key's unions are equial, so
790+
* we can get better split by following columns. Note,
791+
* uninons for attno columns are already done.
792+
*/
793+
794+
return true;
795+
} else {
796+
int MaxGrpId;
791797

792-
v->spl_idgrp = (int *) palloc0(sizeof(int) * entryvec->n);
793-
v->spl_grpflag = (char *) palloc0(sizeof(char) * entryvec->n);
794-
v->spl_ngrp = (int *) palloc(sizeof(int) * entryvec->n);
798+
v->spl_idgrp = (int *) palloc0(sizeof(int) * entryvec->n);
799+
v->spl_grpflag = (char *) palloc0(sizeof(char) * entryvec->n);
800+
v->spl_ngrp = (int *) palloc(sizeof(int) * entryvec->n);
795801

796-
MaxGrpId = gistfindgroup(giststate, entryvec->vector, v, attno);
802+
MaxGrpId = gistfindgroup(giststate, entryvec->vector, v, attno);
797803

798-
/* form union of sub keys for each page (l,p) */
799-
gistunionsubkey(giststate, itup, v, attno + 1);
804+
/* form union of sub keys for each page (l,p) */
805+
gistunionsubkey(giststate, itup, v, attno + 1);
800806

801-
/*
802-
* if possible, we insert equivalent tuples with control by penalty
803-
* for a subkey(s)
804-
*/
805-
if (MaxGrpId > 1)
806-
gistadjsubkey(r, itup, len, v, giststate, attno);
807+
/*
808+
* if possible, we insert equivalent tuples with control by penalty
809+
* for a subkey(s)
810+
*/
811+
if (MaxGrpId > 1)
812+
gistadjsubkey(r, itup, len, v, giststate, attno);
813+
}
807814
}
815+
816+
return false;
808817
}
809818

810819
/*

src/include/access/gist_private.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.16 2006/05/24 11:01:39 teodor Exp $
10+
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.17 2006/05/29 12:50:06 teodor Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -312,7 +312,7 @@ extern void GISTInitBuffer(Buffer b, uint32 f);
312312
extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
313313
Datum k, Relation r, Page pg, OffsetNumber o,
314314
int b, bool l, bool isNull);
315-
void gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GIST_SPLITVEC *v,
315+
bool gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GIST_SPLITVEC *v,
316316
IndexTuple *itup, int len, GISTSTATE *giststate);
317317

318318
/* gistvacuum.c */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy