diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-09-08 12:51:42 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-09-08 12:51:42 -0300 |
commit | 1aba62ec635f5852bc45ce65482366e541e61ff5 (patch) | |
tree | 1161cc00324cb8d229b831a944432646ae1552d5 /src/backend/executor/nodeBitmapHeapscan.c | |
parent | 665a00c9e2598e3be366cb9f99c0a04a51dd8c7a (diff) | |
download | postgresql-1aba62ec635f5852bc45ce65482366e541e61ff5.tar.gz postgresql-1aba62ec635f5852bc45ce65482366e541e61ff5.zip |
Allow per-tablespace effective_io_concurrency
Per discussion, nowadays it is possible to have tablespaces that have
wildly different I/O characteristics from others. Setting different
effective_io_concurrency parameters for those has been measured to
improve performance.
Author: Julien Rouhaud
Reviewed by: Andres Freund
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; /* |