aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeBitmapHeapscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeBitmapHeapscan.c')
-rw-r--r--src/backend/executor/nodeBitmapHeapscan.c35
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;
/*