diff options
Diffstat (limited to 'src/backend/access/gist/gistbuild.c')
-rw-r--r-- | src/backend/access/gist/gistbuild.c | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index 28bc5855ad9..9d3fa9c3b75 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -180,9 +180,7 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) MemoryContext oldcxt = CurrentMemoryContext; int fillfactor; Oid SortSupportFnOids[INDEX_MAX_KEYS]; - bool hasallsortsupports; - int keyscount = IndexRelationGetNumberOfKeyAttributes(index); - GiSTOptions *options = NULL; + GiSTOptions *options = (GiSTOptions *) index->rd_options; /* * We expect to be called exactly once for any index relation. If that's @@ -192,9 +190,6 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) elog(ERROR, "index \"%s\" already contains data", RelationGetRelationName(index)); - if (index->rd_options) - options = (GiSTOptions *) index->rd_options; - buildstate.indexrel = index; buildstate.heaprel = heap; buildstate.sortstate = NULL; @@ -208,33 +203,17 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) buildstate.giststate->tempCxt = createTempGistContext(); /* - * Choose build strategy. If all keys support sorting, do that. Otherwise - * the default strategy is switch to buffering mode when the index grows - * too large to fit in cache. + * Choose build strategy. First check whether the user specified to use + * buffering mode. (The use-case for that in the field is somewhat + * questionable perhaps, but it's important for testing purposes.) */ - hasallsortsupports = true; - for (int i = 0; i < keyscount; i++) - { - SortSupportFnOids[i] = index_getprocid(index, i + 1, - GIST_SORTSUPPORT_PROC); - if (!OidIsValid(SortSupportFnOids[i])) - { - hasallsortsupports = false; - break; - } - } - - if (hasallsortsupports) - { - buildstate.buildMode = GIST_SORTED_BUILD; - } - else if (options) + if (options) { if (options->buffering_mode == GIST_OPTION_BUFFERING_ON) buildstate.buildMode = GIST_BUFFERING_STATS; else if (options->buffering_mode == GIST_OPTION_BUFFERING_OFF) buildstate.buildMode = GIST_BUFFERING_DISABLED; - else + else /* must be "auto" */ buildstate.buildMode = GIST_BUFFERING_AUTO; } else @@ -243,6 +222,28 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) } /* + * Unless buffering mode was forced, see if we can use sorting instead. + */ + if (buildstate.buildMode != GIST_BUFFERING_STATS) + { + bool hasallsortsupports = true; + int keyscount = IndexRelationGetNumberOfKeyAttributes(index); + + for (int i = 0; i < keyscount; i++) + { + SortSupportFnOids[i] = index_getprocid(index, i + 1, + GIST_SORTSUPPORT_PROC); + if (!OidIsValid(SortSupportFnOids[i])) + { + hasallsortsupports = false; + break; + } + } + if (hasallsortsupports) + buildstate.buildMode = GIST_SORTED_BUILD; + } + + /* * Calculate target amount of free space to leave on pages. */ fillfactor = options ? options->fillfactor : GIST_DEFAULT_FILLFACTOR; @@ -852,7 +853,10 @@ gistBuildCallback(Relation index, * and switch to buffering mode if it has. * * To avoid excessive calls to smgrnblocks(), only check this every - * BUFFERING_MODE_SWITCH_CHECK_STEP index tuples + * BUFFERING_MODE_SWITCH_CHECK_STEP index tuples. + * + * In 'stats' state, switch as soon as we have seen enough tuples to have + * some idea of the average tuple size. */ if ((buildstate->buildMode == GIST_BUFFERING_AUTO && buildstate->indtuples % BUFFERING_MODE_SWITCH_CHECK_STEP == 0 && |