@@ -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 ;
@@ -2055,6 +2057,10 @@ ExplainNode(PlanState *planstate, List *ancestors,
2055
2057
if (es -> wal && planstate -> instrument )
2056
2058
show_wal_usage (es , & planstate -> instrument -> walusage );
2057
2059
2060
+ /* Show prefetch usage */
2061
+ if (es -> prefetch && planstate -> instrument )
2062
+ show_prefetch_info (es , & planstate -> instrument -> bufusage .prefetch );
2063
+
2058
2064
/* Prepare per-worker buffer/WAL usage */
2059
2065
if (es -> workers_state && (es -> buffers || es -> wal ) && es -> verbose )
2060
2066
{
@@ -3490,6 +3496,34 @@ explain_get_index_name(Oid indexId)
3490
3496
return result ;
3491
3497
}
3492
3498
3499
+ /*
3500
+ * Show prefetch statistics
3501
+ */
3502
+ static void
3503
+ show_prefetch_info (ExplainState * es , const PrefetchInfo * prefetch_info )
3504
+ {
3505
+ if (es -> format == EXPLAIN_FORMAT_TEXT )
3506
+ {
3507
+ ExplainIndentText (es );
3508
+ appendStringInfo (es -> str , "Prefetch: hits=%lld misses=%lld expired=%lld duplicates=%lld\n" ,
3509
+ (long long ) prefetch_info -> hits ,
3510
+ (long long ) prefetch_info -> misses ,
3511
+ (long long ) prefetch_info -> expired ,
3512
+ (long long ) prefetch_info -> duplicates );
3513
+ }
3514
+ else
3515
+ {
3516
+ ExplainPropertyInteger ("Prefetch Hits" , NULL ,
3517
+ prefetch_info -> hits , es );
3518
+ ExplainPropertyInteger ("Prefetch Misses" , NULL ,
3519
+ prefetch_info -> misses , es );
3520
+ ExplainPropertyInteger ("Prefetch Expired Requests" , NULL ,
3521
+ prefetch_info -> expired , es );
3522
+ ExplainPropertyInteger ("Prefetch Duplicated Requests" , NULL ,
3523
+ prefetch_info -> duplicates , es );
3524
+ }
3525
+ }
3526
+
3493
3527
/*
3494
3528
* Show buffer usage details.
3495
3529
*/
0 commit comments