From 5a1e6df3b84c91957f80b19edb497a5eec83c403 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Tue, 9 Jul 2024 12:15:47 +1200 Subject: Show Parallel Bitmap Heap Scan worker stats in EXPLAIN ANALYZE Nodes like Memoize report the cache stats for each parallel worker, so it makes sense to show the exact and lossy pages in Parallel Bitmap Heap Scan in a similar way. Likewise, Sort shows the method and memory used for each worker. There was some discussion on whether the leader stats should include the totals for each parallel worker or not. I did some analysis on this to see what other parallel node types do and it seems only Parallel Hash does anything like this. All the rest, per what's supported by ExecParallelRetrieveInstrumentation() are consistent with each other. Author: David Geier Author: Heikki Linnakangas Author: Donghang Lin Author: Alena Rybakina Author: David Rowley Reviewed-by: Dmitry Dolgov <9erthalion6@gmail.com> Reviewed-by: Michael Christofides Reviewed-by: Robert Haas Reviewed-by: Dilip Kumar Reviewed-by: Tomas Vondra Reviewed-by: Melanie Plageman Reviewed-by: Donghang Lin Reviewed-by: Masahiro Ikeda Discussion: https://postgr.es/m/b3d80961-c2e5-38cc-6a32-61886cdf766d%40gmail.com --- src/backend/commands/explain.c | 58 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'src/backend/commands/explain.c') diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 6defd26df50..118db12903c 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -2010,8 +2010,7 @@ ExplainNode(PlanState *planstate, List *ancestors, if (plan->qual) show_instrumentation_count("Rows Removed by Filter", 1, planstate, es); - if (es->analyze) - show_tidbitmap_info((BitmapHeapScanState *) planstate, es); + show_tidbitmap_info((BitmapHeapScanState *) planstate, es); break; case T_SampleScan: show_tablesample(((SampleScan *) plan)->tablesample, @@ -3628,31 +3627,70 @@ show_hashagg_info(AggState *aggstate, ExplainState *es) } /* - * If it's EXPLAIN ANALYZE, show exact/lossy pages for a BitmapHeapScan node + * Show exact/lossy pages for a BitmapHeapScan node */ static void show_tidbitmap_info(BitmapHeapScanState *planstate, ExplainState *es) { + if (!es->analyze) + return; + if (es->format != EXPLAIN_FORMAT_TEXT) { ExplainPropertyUInteger("Exact Heap Blocks", NULL, - planstate->exact_pages, es); + planstate->stats.exact_pages, es); ExplainPropertyUInteger("Lossy Heap Blocks", NULL, - planstate->lossy_pages, es); + planstate->stats.lossy_pages, es); } else { - if (planstate->exact_pages > 0 || planstate->lossy_pages > 0) + if (planstate->stats.exact_pages > 0 || planstate->stats.lossy_pages > 0) { ExplainIndentText(es); appendStringInfoString(es->str, "Heap Blocks:"); - if (planstate->exact_pages > 0) - appendStringInfo(es->str, " exact=" UINT64_FORMAT, planstate->exact_pages); - if (planstate->lossy_pages > 0) - appendStringInfo(es->str, " lossy=" UINT64_FORMAT, planstate->lossy_pages); + if (planstate->stats.exact_pages > 0) + appendStringInfo(es->str, " exact=" UINT64_FORMAT, planstate->stats.exact_pages); + if (planstate->stats.lossy_pages > 0) + appendStringInfo(es->str, " lossy=" UINT64_FORMAT, planstate->stats.lossy_pages); appendStringInfoChar(es->str, '\n'); } } + + /* Display stats for each parallel worker */ + if (planstate->pstate != NULL) + { + for (int n = 0; n < planstate->sinstrument->num_workers; n++) + { + BitmapHeapScanInstrumentation *si = &planstate->sinstrument->sinstrument[n]; + + if (si->exact_pages == 0 && si->lossy_pages == 0) + continue; + + if (es->workers_state) + ExplainOpenWorker(n, es); + + if (es->format == EXPLAIN_FORMAT_TEXT) + { + ExplainIndentText(es); + appendStringInfoString(es->str, "Heap Blocks:"); + if (si->exact_pages > 0) + appendStringInfo(es->str, " exact=" UINT64_FORMAT, si->exact_pages); + if (si->lossy_pages > 0) + appendStringInfo(es->str, " lossy=" UINT64_FORMAT, si->lossy_pages); + appendStringInfoChar(es->str, '\n'); + } + else + { + ExplainPropertyUInteger("Exact Heap Blocks", NULL, + si->exact_pages, es); + ExplainPropertyUInteger("Lossy Heap Blocks", NULL, + si->lossy_pages, es); + } + + if (es->workers_state) + ExplainCloseWorker(n, es); + } + } } /* -- cgit v1.2.3