Make IndexScanInstrumentation a pointer in executor scan nodes.

Change the IndexScanInstrumentation fields in IndexScanState,
IndexOnlyScanState, and BitmapIndexScanState from inline structs to
pointers.  This avoids additional space overhead whenever new fields are
added to IndexScanInstrumentation in the future, at least in the common
case where the instrumentation isn't used (i.e. when the executor node
isn't being run through an EXPLAIN ANALYZE).

Preparation for an upcoming patch series that will add index
prefetching.  The new slot-based interface that will enable index
prefetching necessitates that we add at least one more field to
IndexScanInstrumentation (to count heap fetches during index-only
scans).

Author: Peter Geoghegan <pg@bowt.ie>
Reviewed-By: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/CAH2-Wz=g=JTSyDB4UtB5su2ZcvsS7VbP+ZMvvaG6ABoCb+s8Lw@mail.gmail.com
This commit is contained in:
Peter Geoghegan 2026-03-22 13:20:29 -04:00
parent 4f7ecca84d
commit f026fbf059
5 changed files with 29 additions and 17 deletions

View file

@ -3880,7 +3880,7 @@ show_indexsearches_info(PlanState *planstate, ExplainState *es)
{
IndexScanState *indexstate = ((IndexScanState *) planstate);
nsearches = indexstate->iss_Instrument.nsearches;
nsearches = indexstate->iss_Instrument->nsearches;
SharedInfo = indexstate->iss_SharedInfo;
break;
}
@ -3888,7 +3888,7 @@ show_indexsearches_info(PlanState *planstate, ExplainState *es)
{
IndexOnlyScanState *indexstate = ((IndexOnlyScanState *) planstate);
nsearches = indexstate->ioss_Instrument.nsearches;
nsearches = indexstate->ioss_Instrument->nsearches;
SharedInfo = indexstate->ioss_SharedInfo;
break;
}
@ -3896,7 +3896,7 @@ show_indexsearches_info(PlanState *planstate, ExplainState *es)
{
BitmapIndexScanState *indexstate = ((BitmapIndexScanState *) planstate);
nsearches = indexstate->biss_Instrument.nsearches;
nsearches = indexstate->biss_Instrument->nsearches;
SharedInfo = indexstate->biss_SharedInfo;
break;
}

View file

@ -203,7 +203,7 @@ ExecEndBitmapIndexScan(BitmapIndexScanState *node)
* shutdown on the workers. On rescan it will spin up new workers
* which will have a new BitmapIndexScanState and zeroed stats.
*/
winstrument->nsearches += node->biss_Instrument.nsearches;
winstrument->nsearches += node->biss_Instrument->nsearches;
}
/*
@ -274,6 +274,10 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
return indexstate;
/* Set up instrumentation of bitmap index scans if requested */
if (estate->es_instrument)
indexstate->biss_Instrument = palloc0_object(IndexScanInstrumentation);
/* Open the index relation. */
lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode;
indexstate->biss_RelationDesc = index_open(node->indexid, lockmode);
@ -325,7 +329,7 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
indexstate->biss_ScanDesc =
index_beginscan_bitmap(indexstate->biss_RelationDesc,
estate->es_snapshot,
&indexstate->biss_Instrument,
indexstate->biss_Instrument,
indexstate->biss_NumScanKeys);
/*

View file

@ -93,7 +93,7 @@ IndexOnlyNext(IndexOnlyScanState *node)
scandesc = index_beginscan(node->ss.ss_currentRelation,
node->ioss_RelationDesc,
estate->es_snapshot,
&node->ioss_Instrument,
node->ioss_Instrument,
node->ioss_NumScanKeys,
node->ioss_NumOrderByKeys);
@ -433,7 +433,7 @@ ExecEndIndexOnlyScan(IndexOnlyScanState *node)
* shutdown on the workers. On rescan it will spin up new workers
* which will have a new IndexOnlyScanState and zeroed stats.
*/
winstrument->nsearches += node->ioss_Instrument.nsearches;
winstrument->nsearches += node->ioss_Instrument->nsearches;
}
/*
@ -606,6 +606,10 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
return indexstate;
/* Set up instrumentation of index-only scans if requested */
if (estate->es_instrument)
indexstate->ioss_Instrument = palloc0_object(IndexScanInstrumentation);
/* Open the index relation. */
lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode;
indexRelation = index_open(node->indexid, lockmode);
@ -787,7 +791,7 @@ ExecIndexOnlyScanInitializeDSM(IndexOnlyScanState *node,
node->ioss_ScanDesc =
index_beginscan_parallel(node->ss.ss_currentRelation,
node->ioss_RelationDesc,
&node->ioss_Instrument,
node->ioss_Instrument,
node->ioss_NumScanKeys,
node->ioss_NumOrderByKeys,
piscan);
@ -853,7 +857,7 @@ ExecIndexOnlyScanInitializeWorker(IndexOnlyScanState *node,
node->ioss_ScanDesc =
index_beginscan_parallel(node->ss.ss_currentRelation,
node->ioss_RelationDesc,
&node->ioss_Instrument,
node->ioss_Instrument,
node->ioss_NumScanKeys,
node->ioss_NumOrderByKeys,
piscan);

View file

@ -111,7 +111,7 @@ IndexNext(IndexScanState *node)
scandesc = index_beginscan(node->ss.ss_currentRelation,
node->iss_RelationDesc,
estate->es_snapshot,
&node->iss_Instrument,
node->iss_Instrument,
node->iss_NumScanKeys,
node->iss_NumOrderByKeys);
@ -207,7 +207,7 @@ IndexNextWithReorder(IndexScanState *node)
scandesc = index_beginscan(node->ss.ss_currentRelation,
node->iss_RelationDesc,
estate->es_snapshot,
&node->iss_Instrument,
node->iss_Instrument,
node->iss_NumScanKeys,
node->iss_NumOrderByKeys);
@ -813,7 +813,7 @@ ExecEndIndexScan(IndexScanState *node)
* shutdown on the workers. On rescan it will spin up new workers
* which will have a new IndexOnlyScanState and zeroed stats.
*/
winstrument->nsearches += node->iss_Instrument.nsearches;
winstrument->nsearches += node->iss_Instrument->nsearches;
}
/*
@ -974,6 +974,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
return indexstate;
/* Set up instrumentation of index scans if requested */
if (estate->es_instrument)
indexstate->iss_Instrument = palloc0_object(IndexScanInstrumentation);
/* Open the index relation. */
lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode;
indexstate->iss_RelationDesc = index_open(node->indexid, lockmode);
@ -1723,7 +1727,7 @@ ExecIndexScanInitializeDSM(IndexScanState *node,
node->iss_ScanDesc =
index_beginscan_parallel(node->ss.ss_currentRelation,
node->iss_RelationDesc,
&node->iss_Instrument,
node->iss_Instrument,
node->iss_NumScanKeys,
node->iss_NumOrderByKeys,
piscan);
@ -1787,7 +1791,7 @@ ExecIndexScanInitializeWorker(IndexScanState *node,
node->iss_ScanDesc =
index_beginscan_parallel(node->ss.ss_currentRelation,
node->iss_RelationDesc,
&node->iss_Instrument,
node->iss_Instrument,
node->iss_NumScanKeys,
node->iss_NumOrderByKeys,
piscan);

View file

@ -1732,7 +1732,7 @@ typedef struct IndexScanState
ExprContext *iss_RuntimeContext;
Relation iss_RelationDesc;
struct IndexScanDescData *iss_ScanDesc;
IndexScanInstrumentation iss_Instrument;
IndexScanInstrumentation *iss_Instrument;
SharedIndexScanInstrumentation *iss_SharedInfo;
/* These are needed for re-checking ORDER BY expr ordering */
@ -1783,7 +1783,7 @@ typedef struct IndexOnlyScanState
ExprContext *ioss_RuntimeContext;
Relation ioss_RelationDesc;
struct IndexScanDescData *ioss_ScanDesc;
IndexScanInstrumentation ioss_Instrument;
IndexScanInstrumentation *ioss_Instrument;
SharedIndexScanInstrumentation *ioss_SharedInfo;
TupleTableSlot *ioss_TableSlot;
Buffer ioss_VMBuffer;
@ -1824,7 +1824,7 @@ typedef struct BitmapIndexScanState
ExprContext *biss_RuntimeContext;
Relation biss_RelationDesc;
struct IndexScanDescData *biss_ScanDesc;
IndexScanInstrumentation biss_Instrument;
IndexScanInstrumentation *biss_Instrument;
SharedIndexScanInstrumentation *biss_SharedInfo;
} BitmapIndexScanState;