*** a/src/backend/commands/explain.c --- b/src/backend/commands/explain.c *************** *** 975,992 **** ExplainNode(PlanState *planstate, List *ancestors, double startup_sec = 1000.0 * planstate->instrument->startup / nloops; double total_sec = 1000.0 * planstate->instrument->total / nloops; double rows = planstate->instrument->ntuples / nloops; if (es->format == EXPLAIN_FORMAT_TEXT) { appendStringInfo(es->str, ! " (actual time=%.3f..%.3f rows=%.0f loops=%.0f)", ! startup_sec, total_sec, rows, nloops); } else { ExplainPropertyFloat("Actual Startup Time", startup_sec, 3, es); ExplainPropertyFloat("Actual Total Time", total_sec, 3, es); ExplainPropertyFloat("Actual Rows", rows, 0, es); ExplainPropertyFloat("Actual Loops", nloops, 0, es); } } --- 975,994 ---- double startup_sec = 1000.0 * planstate->instrument->startup / nloops; double total_sec = 1000.0 * planstate->instrument->total / nloops; double rows = planstate->instrument->ntuples / nloops; + double filtered = planstate->instrument->nfiltered / nloops; if (es->format == EXPLAIN_FORMAT_TEXT) { appendStringInfo(es->str, ! " (actual time=%.3f..%.3f rows=%.0f filtered=%.0f loops=%.0f)", ! startup_sec, total_sec, rows, filtered, nloops); } else { ExplainPropertyFloat("Actual Startup Time", startup_sec, 3, es); ExplainPropertyFloat("Actual Total Time", total_sec, 3, es); ExplainPropertyFloat("Actual Rows", rows, 0, es); + ExplainPropertyFloat("Rows Filtered", rows, 0, es); ExplainPropertyFloat("Actual Loops", nloops, 0, es); } } *************** *** 999,1004 **** ExplainNode(PlanState *planstate, List *ancestors, --- 1001,1007 ---- ExplainPropertyFloat("Actual Startup Time", 0.0, 3, es); ExplainPropertyFloat("Actual Total Time", 0.0, 3, es); ExplainPropertyFloat("Actual Rows", 0.0, 0, es); + ExplainPropertyFloat("Rows Filtered", 0.0, 0, es); ExplainPropertyFloat("Actual Loops", 0.0, 0, es); } } *** a/src/backend/executor/execScan.c --- b/src/backend/executor/execScan.c *************** *** 19,24 **** --- 19,25 ---- #include "postgres.h" #include "executor/executor.h" + #include "executor/instrument.h" #include "miscadmin.h" #include "utils/memutils.h" *************** *** 221,226 **** ExecScan(ScanState *node, --- 222,229 ---- * Tuple fails qual, so free per-tuple memory and try again. */ ResetExprContext(econtext); + if (node->ps.instrument) + node->ps.instrument->nfiltered += 1; } } *** a/src/include/executor/instrument.h --- b/src/include/executor/instrument.h *************** *** 49,54 **** typedef struct Instrumentation --- 49,55 ---- double startup; /* Total startup time (in seconds) */ double total; /* Total total time (in seconds) */ double ntuples; /* Total tuples produced */ + double nfiltered; /* Total tuples filtered by qual */ double nloops; /* # of run cycles for this node */ BufferUsage bufusage; /* Total buffer usage */ } Instrumentation;