diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/brin/brin.c | 1 | ||||
-rw-r--r-- | src/backend/access/gin/ginscan.c | 1 | ||||
-rw-r--r-- | src/backend/access/gist/gistget.c | 2 | ||||
-rw-r--r-- | src/backend/access/hash/hashsearch.c | 1 | ||||
-rw-r--r-- | src/backend/access/index/genam.c | 1 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtree.c | 15 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtsearch.c | 1 | ||||
-rw-r--r-- | src/backend/access/spgist/spgscan.c | 1 | ||||
-rw-r--r-- | src/backend/commands/explain.c | 40 |
9 files changed, 63 insertions, 0 deletions
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 75a65ec9c75..9f146c12a85 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -591,6 +591,7 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) opaque = (BrinOpaque *) scan->opaque; bdesc = opaque->bo_bdesc; pgstat_count_index_scan(idxRel); + scan->nsearches++; /* * We need to know the size of the table so that we know how long to diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c index 63ded6301e2..8c1bbf36644 100644 --- a/src/backend/access/gin/ginscan.c +++ b/src/backend/access/gin/ginscan.c @@ -437,6 +437,7 @@ ginNewScanKey(IndexScanDesc scan) MemoryContextSwitchTo(oldCtx); pgstat_count_index_scan(scan->indexRelation); + scan->nsearches++; } void diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index cc40e928e0a..609e85fdae1 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -625,6 +625,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir) GISTSearchItem fakeItem; pgstat_count_index_scan(scan->indexRelation); + scan->nsearches++; so->firstCall = false; so->curPageData = so->nPageData = 0; @@ -750,6 +751,7 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) return 0; pgstat_count_index_scan(scan->indexRelation); + scan->nsearches++; /* Begin the scan by processing the root page */ so->curPageData = so->nPageData = 0; diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c index a3a1fccf33b..c4f73043772 100644 --- a/src/backend/access/hash/hashsearch.c +++ b/src/backend/access/hash/hashsearch.c @@ -298,6 +298,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir) HashScanPosItem *currItem; pgstat_count_index_scan(rel); + scan->nsearches++; /* * We do not support hash scans with no index qualification, because we diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index 07bae342e25..0cabfa5de5d 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -119,6 +119,7 @@ RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys) scan->ignore_killed_tuples = !scan->xactStartedInRecovery; scan->opaque = NULL; + scan->nsearches = 0; scan->xs_itup = NULL; scan->xs_itupdesc = NULL; diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 45ea6afba1d..eabd54b8c3d 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -70,6 +70,7 @@ typedef struct BTParallelScanDescData BTPS_State btps_pageStatus; /* indicates whether next page is * available for scan. see above for * possible states of parallel scan. */ + uint64 btps_nsearches; /* tracked for IndexScanDescData.nsearches */ slock_t btps_mutex; /* protects above variables, btps_arrElems */ ConditionVariable btps_cv; /* used to synchronize parallel scan */ @@ -557,6 +558,7 @@ btinitparallelscan(void *target) bt_target->btps_nextScanPage = InvalidBlockNumber; bt_target->btps_lastCurrPage = InvalidBlockNumber; bt_target->btps_pageStatus = BTPARALLEL_NOT_INITIALIZED; + bt_target->btps_nsearches = 0; ConditionVariableInit(&bt_target->btps_cv); } @@ -583,6 +585,7 @@ btparallelrescan(IndexScanDesc scan) btscan->btps_nextScanPage = InvalidBlockNumber; btscan->btps_lastCurrPage = InvalidBlockNumber; btscan->btps_pageStatus = BTPARALLEL_NOT_INITIALIZED; + /* deliberately don't reset btps_nsearches (matches index_rescan) */ SpinLockRelease(&btscan->btps_mutex); } @@ -676,6 +679,7 @@ _bt_parallel_seize(IndexScanDesc scan, BlockNumber *next_scan_page, { /* Can start scheduled primitive scan right away, so do so */ btscan->btps_pageStatus = BTPARALLEL_ADVANCING; + btscan->btps_nsearches++; for (int i = 0; i < so->numArrayKeys; i++) { BTArrayKeyInfo *array = &so->arrayKeys[i]; @@ -712,6 +716,11 @@ _bt_parallel_seize(IndexScanDesc scan, BlockNumber *next_scan_page, */ btscan->btps_pageStatus = BTPARALLEL_ADVANCING; Assert(btscan->btps_nextScanPage != P_NONE); + if (btscan->btps_nextScanPage == InvalidBlockNumber) + { + Assert(first); + btscan->btps_nsearches++; + } *next_scan_page = btscan->btps_nextScanPage; *last_curr_page = btscan->btps_lastCurrPage; exit_loop = true; @@ -810,6 +819,12 @@ _bt_parallel_done(IndexScanDesc scan) btscan->btps_pageStatus = BTPARALLEL_DONE; status_changed = true; } + + /* + * Don't use local nsearches counter -- overwrite it with the nsearches + * counter that we've been maintaining in shared memory + */ + scan->nsearches = btscan->btps_nsearches; SpinLockRelease(&btscan->btps_mutex); /* wake up all the workers associated with this parallel scan */ diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 472ce06f190..941b4eaaf18 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -950,6 +950,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) * _bt_search/_bt_endpoint below */ pgstat_count_index_scan(rel); + scan->nsearches++; /*---------- * Examine the scan keys to discover where we need to start the scan. diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c index 53f910e9d89..8554b453555 100644 --- a/src/backend/access/spgist/spgscan.c +++ b/src/backend/access/spgist/spgscan.c @@ -421,6 +421,7 @@ spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, /* count an indexscan for stats */ pgstat_count_index_scan(scan->indexRelation); + scan->nsearches++; } void diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index d8a7232cedb..78d5d0b67c4 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -13,6 +13,7 @@ */ #include "postgres.h" +#include "access/relscan.h" #include "access/xact.h" #include "catalog/pg_type.h" #include "commands/createas.h" @@ -125,6 +126,7 @@ static void show_recursive_union_info(RecursiveUnionState *rstate, static void show_memoize_info(MemoizeState *mstate, List *ancestors, ExplainState *es); static void show_hashagg_info(AggState *aggstate, ExplainState *es); +static void show_indexsearches_info(PlanState *planstate, ExplainState *es); static void show_tidbitmap_info(BitmapHeapScanState *planstate, ExplainState *es); static void show_instrumentation_count(const char *qlabel, int which, @@ -2096,6 +2098,7 @@ ExplainNode(PlanState *planstate, List *ancestors, if (plan->qual) show_instrumentation_count("Rows Removed by Filter", 1, planstate, es); + show_indexsearches_info(planstate, es); break; case T_IndexOnlyScan: show_scan_qual(((IndexOnlyScan *) plan)->indexqual, @@ -2112,10 +2115,12 @@ ExplainNode(PlanState *planstate, List *ancestors, if (es->analyze) ExplainPropertyFloat("Heap Fetches", NULL, planstate->instrument->ntuples2, 0, es); + show_indexsearches_info(planstate, es); break; case T_BitmapIndexScan: show_scan_qual(((BitmapIndexScan *) plan)->indexqualorig, "Index Cond", planstate, ancestors, es); + show_indexsearches_info(planstate, es); break; case T_BitmapHeapScan: show_scan_qual(((BitmapHeapScan *) plan)->bitmapqualorig, @@ -3856,6 +3861,41 @@ show_hashagg_info(AggState *aggstate, ExplainState *es) } /* + * Show the total number of index searches performed by a + * IndexScan/IndexOnlyScan/BitmapIndexScan node + */ +static void +show_indexsearches_info(PlanState *planstate, ExplainState *es) +{ + Plan *plan = planstate->plan; + struct IndexScanDescData *scanDesc = NULL; + uint64 nsearches = 0; + + if (!es->analyze) + return; + + switch (nodeTag(plan)) + { + case T_IndexScan: + scanDesc = ((IndexScanState *) planstate)->iss_ScanDesc; + break; + case T_IndexOnlyScan: + scanDesc = ((IndexOnlyScanState *) planstate)->ioss_ScanDesc; + break; + case T_BitmapIndexScan: + scanDesc = ((BitmapIndexScanState *) planstate)->biss_ScanDesc; + break; + default: + break; + } + + if (scanDesc) + nsearches = scanDesc->nsearches; + + ExplainPropertyUInteger("Index Searches", NULL, nsearches, es); +} + +/* * Show exact/lossy pages for a BitmapHeapScan node */ static void |