diff options
Diffstat (limited to 'src/backend/executor/nodeBitmapHeapscan.c')
-rw-r--r-- | src/backend/executor/nodeBitmapHeapscan.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index 4597437178a..c784b9e7a38 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -44,6 +44,7 @@ #include "storage/predicate.h" #include "utils/memutils.h" #include "utils/rel.h" +#include "utils/spccache.h" #include "utils/snapmgr.h" #include "utils/tqual.h" @@ -95,9 +96,8 @@ BitmapHeapNext(BitmapHeapScanState *node) * prefetching. node->prefetch_pages tracks exactly how many pages ahead * the prefetch iterator is. Also, node->prefetch_target tracks the * desired prefetch distance, which starts small and increases up to the - * GUC-controlled maximum, target_prefetch_pages. This is to avoid doing - * a lot of prefetching in a scan that stops after a few tuples because of - * a LIMIT. + * node->prefetch_maximum. This is to avoid doing a lot of prefetching in + * a scan that stops after a few tuples because of a LIMIT. */ if (tbm == NULL) { @@ -111,7 +111,7 @@ BitmapHeapNext(BitmapHeapScanState *node) node->tbmres = tbmres = NULL; #ifdef USE_PREFETCH - if (target_prefetch_pages > 0) + if (node->prefetch_maximum > 0) { node->prefetch_iterator = prefetch_iterator = tbm_begin_iterate(tbm); node->prefetch_pages = 0; @@ -188,10 +188,10 @@ BitmapHeapNext(BitmapHeapScanState *node) * page/tuple, then to one after the second tuple is fetched, then * it doubles as later pages are fetched. */ - if (node->prefetch_target >= target_prefetch_pages) + if (node->prefetch_target >= node->prefetch_maximum) /* don't increase any further */ ; - else if (node->prefetch_target >= target_prefetch_pages / 2) - node->prefetch_target = target_prefetch_pages; + else if (node->prefetch_target >= node->prefetch_maximum / 2) + node->prefetch_target = node->prefetch_maximum; else if (node->prefetch_target > 0) node->prefetch_target *= 2; else @@ -211,7 +211,7 @@ BitmapHeapNext(BitmapHeapScanState *node) * Try to prefetch at least a few pages even before we get to the * second page if we don't stop reading after the first tuple. */ - if (node->prefetch_target < target_prefetch_pages) + if (node->prefetch_target < node->prefetch_maximum) node->prefetch_target++; #endif /* USE_PREFETCH */ } @@ -539,6 +539,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) { BitmapHeapScanState *scanstate; Relation currentRelation; + int io_concurrency; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); @@ -564,6 +565,8 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) scanstate->prefetch_iterator = NULL; scanstate->prefetch_pages = 0; scanstate->prefetch_target = 0; + /* may be updated below */ + scanstate->prefetch_maximum = target_prefetch_pages; /* * Miscellaneous initialization @@ -598,6 +601,22 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); + /* + * Determine the maximum for prefetch_target. If the tablespace has a + * specific IO concurrency set, use that to compute the corresponding + * maximum value; otherwise, we already initialized to the value computed + * by the GUC machinery. + */ + io_concurrency = + get_tablespace_io_concurrency(currentRelation->rd_rel->reltablespace); + if (io_concurrency != effective_io_concurrency) + { + double maximum; + + if (ComputeIoConcurrency(io_concurrency, &maximum)) + scanstate->prefetch_maximum = rint(maximum); + } + scanstate->ss.ss_currentRelation = currentRelation; /* |