@@ -47,7 +47,6 @@ ExplainOneQuery_hook_type ExplainOneQuery_hook = NULL;
47
47
/* Hook for plugins to get control in explain_get_index_name() */
48
48
explain_get_index_name_hook_type explain_get_index_name_hook = NULL ;
49
49
50
-
51
50
/* OR-able flags for ExplainXMLTag() */
52
51
#define X_OPENING 0
53
52
#define X_CLOSING 1
@@ -121,6 +120,7 @@ static void show_eval_params(Bitmapset *bms_params, ExplainState *es);
121
120
static const char * explain_get_index_name (Oid indexId );
122
121
static void show_buffer_usage (ExplainState * es , const BufferUsage * usage ,
123
122
bool planning );
123
+ static void show_prefetch_info (ExplainState * es , const PrefetchInfo * prefetch_info );
124
124
static void show_wal_usage (ExplainState * es , const WalUsage * usage );
125
125
static void ExplainIndexScanDetails (Oid indexid , ScanDirection indexorderdir ,
126
126
ExplainState * es );
@@ -186,6 +186,8 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
186
186
es -> costs = defGetBoolean (opt );
187
187
else if (strcmp (opt -> defname , "buffers" ) == 0 )
188
188
es -> buffers = defGetBoolean (opt );
189
+ else if (strcmp (opt -> defname , "prefetch" ) == 0 )
190
+ es -> prefetch = defGetBoolean (opt );
189
191
else if (strcmp (opt -> defname , "wal" ) == 0 )
190
192
es -> wal = defGetBoolean (opt );
191
193
else if (strcmp (opt -> defname , "settings" ) == 0 )
@@ -534,7 +536,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es,
534
536
else if (es -> analyze )
535
537
instrument_option |= INSTRUMENT_ROWS ;
536
538
537
- if (es -> buffers )
539
+ if (es -> buffers || es -> prefetch )
538
540
instrument_option |= INSTRUMENT_BUFFERS ;
539
541
if (es -> wal )
540
542
instrument_option |= INSTRUMENT_WAL ;
@@ -2066,6 +2068,10 @@ ExplainNode(PlanState *planstate, List *ancestors,
2066
2068
if (es -> wal && planstate -> instrument )
2067
2069
show_wal_usage (es , & planstate -> instrument -> walusage );
2068
2070
2071
+ /* Show prefetch usage */
2072
+ if (es -> prefetch && planstate -> instrument )
2073
+ show_prefetch_info (es , & planstate -> instrument -> bufusage .prefetch );
2074
+
2069
2075
/* Prepare per-worker buffer/WAL usage */
2070
2076
if (es -> workers_state && (es -> buffers || es -> wal ) && es -> verbose )
2071
2077
{
@@ -3501,6 +3507,34 @@ explain_get_index_name(Oid indexId)
3501
3507
return result ;
3502
3508
}
3503
3509
3510
+ /*
3511
+ * Show prefetch statistics
3512
+ */
3513
+ static void
3514
+ show_prefetch_info (ExplainState * es , const PrefetchInfo * prefetch_info )
3515
+ {
3516
+ if (es -> format == EXPLAIN_FORMAT_TEXT )
3517
+ {
3518
+ ExplainIndentText (es );
3519
+ appendStringInfo (es -> str , "Prefetch: hits=%lld misses=%lld expired=%lld duplicates=%lld\n" ,
3520
+ (long long ) prefetch_info -> hits ,
3521
+ (long long ) prefetch_info -> misses ,
3522
+ (long long ) prefetch_info -> expired ,
3523
+ (long long ) prefetch_info -> duplicates );
3524
+ }
3525
+ else
3526
+ {
3527
+ ExplainPropertyInteger ("Prefetch Hits" , NULL ,
3528
+ prefetch_info -> hits , es );
3529
+ ExplainPropertyInteger ("Prefetch Misses" , NULL ,
3530
+ prefetch_info -> misses , es );
3531
+ ExplainPropertyInteger ("Prefetch Expired Requests" , NULL ,
3532
+ prefetch_info -> expired , es );
3533
+ ExplainPropertyInteger ("Prefetch Duplicated Requests" , NULL ,
3534
+ prefetch_info -> duplicates , es );
3535
+ }
3536
+ }
3537
+
3504
3538
/*
3505
3539
* Show buffer usage details.
3506
3540
*/
0 commit comments