From 10e3acb8e7bd3298ba2b942f86c18f5ba2e142a8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 13 Nov 2008 17:42:10 +0000 Subject: [PATCH] Prevent synchronous scan during GIN index build, because GIN is optimized for inserting tuples in increasing TID order. It's not clear whether this fully explains Ivan Sergio Borgonovo's complaint, but simple testing confirms that a scan that doesn't start at block 0 can slow GIN build by a factor of three or four. Backpatch to 8.3. Sync scan didn't exist before that. --- src/backend/access/gin/gininsert.c | 9 ++++++--- src/backend/access/gist/gist.c | 4 ++-- src/backend/access/hash/hash.c | 4 ++-- src/backend/access/nbtree/nbtree.c | 4 ++-- src/backend/catalog/index.c | 10 ++++++++-- src/include/catalog/index.h | 3 ++- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index 64099cd1e50..6e0a194a694 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.15 2008/09/30 10:52:10 heikki Exp $ + * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.16 2008/11/13 17:42:09 tgl Exp $ *------------------------------------------------------------------------- */ @@ -340,8 +340,11 @@ ginbuild(PG_FUNCTION_ARGS) buildstate.accum.ginstate = &buildstate.ginstate; ginInitBA(&buildstate.accum); - /* do the heap scan */ - reltuples = IndexBuildHeapScan(heap, index, indexInfo, + /* + * Do the heap scan. We disallow sync scan here because dataPlaceToPage + * prefers to receive tuples in TID order. + */ + reltuples = IndexBuildHeapScan(heap, index, indexInfo, false, ginBuildCallback, (void *) &buildstate); /* dump remaining entries to the index */ diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index e1f068ee7bc..1dff6d2f2ae 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.153 2008/11/03 20:47:48 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.154 2008/11/13 17:42:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -152,7 +152,7 @@ gistbuild(PG_FUNCTION_ARGS) buildstate.tmpCtx = createTempGistContext(); /* do the heap scan */ - reltuples = IndexBuildHeapScan(heap, index, indexInfo, + reltuples = IndexBuildHeapScan(heap, index, indexInfo, true, gistbuildCallback, (void *) &buildstate); /* okay, all heap tuples are indexed */ diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index a24350367fc..86d4df5e4df 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.106 2008/10/17 23:50:57 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.107 2008/11/13 17:42:10 tgl Exp $ * * NOTES * This file contains only the public interface routines. @@ -93,7 +93,7 @@ hashbuild(PG_FUNCTION_ARGS) buildstate.indtuples = 0; /* do the heap scan */ - reltuples = IndexBuildHeapScan(heap, index, indexInfo, + reltuples = IndexBuildHeapScan(heap, index, indexInfo, true, hashbuildCallback, (void *) &buildstate); if (buildstate.spool) diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index f47a8e5f364..bd486afabb7 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -12,7 +12,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.164 2008/10/31 15:04:59 heikki Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.165 2008/11/13 17:42:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -122,7 +122,7 @@ btbuild(PG_FUNCTION_ARGS) buildstate.spool2 = _bt_spoolinit(index, false, true); /* do the heap scan */ - reltuples = IndexBuildHeapScan(heap, index, indexInfo, + reltuples = IndexBuildHeapScan(heap, index, indexInfo, true, btbuildCallback, (void *) &buildstate); /* okay, all heap tuples are indexed */ diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 7c0c313e91b..0ad1e04a748 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.307 2008/11/02 01:45:27 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.308 2008/11/13 17:42:10 tgl Exp $ * * * INTERFACE ROUTINES @@ -1513,6 +1513,7 @@ double IndexBuildHeapScan(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, + bool allow_sync, IndexBuildCallback callback, void *callback_state) { @@ -1575,7 +1576,12 @@ IndexBuildHeapScan(Relation heapRelation, OldestXmin = GetOldestXmin(heapRelation->rd_rel->relisshared, true); } - scan = heap_beginscan(heapRelation, snapshot, 0, NULL); + scan = heap_beginscan_strat(heapRelation, /* relation */ + snapshot, /* snapshot */ + 0, /* number of keys */ + NULL, /* scan key */ + true, /* buffer access strategy OK */ + allow_sync); /* syncscan OK? */ reltuples = 0; diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index a5ab195c233..939c47cd916 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.75 2008/01/01 19:45:56 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.76 2008/11/13 17:42:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -63,6 +63,7 @@ extern void index_build(Relation heapRelation, extern double IndexBuildHeapScan(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, + bool allow_sync, IndexBuildCallback callback, void *callback_state);