From ddb17e387aa28d61521227377b00f997756b8a27 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 21 Feb 2025 16:10:44 -0500 Subject: Allow EXPLAIN to indicate fractional rows. When nloops > 1, we now display two digits after the decimal point, rather than none. This is important because what we print is actually planstate->instrument->ntuples / nloops, and sometimes what you want to know is planstate->instrument->ntuples. You can estimate that by multiplying the displayed row count by the displayed nloops value, but the fact that the displayed value is rounded makes that inexact. It's still inexact even if we show these two extra decimal places, but less so. Perhaps we will agree on a way to further improve this output later, but for now this seems better than doing nothing. Author: Ibrar Ahmed Author: Ilia Evdokimov Reviewed-by: David G. Johnston Reviewed-by: Amit Kapila Reviewed-by: Vignesh C Reviewed-by: Greg Stark Reviewed-by: Naeem Akhter Reviewed-by: Hamid Akhtar Reviewed-by: Tom Lane Reviewed-by: Andrei Lepikhov Reviewed-by: Guillaume Lelarge Reviewed-by: Matheus Alcantara Reviewed-by: Alena Rybakina Discussion: http://postgr.es/m/603c8f070905281830g2e5419c4xad2946d149e21f9d%40mail.gmail.com --- src/backend/commands/explain.c | 50 ++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 16 deletions(-) (limited to 'src/backend/commands/explain.c') diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index c368261eeef..c0d614866a9 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -1993,14 +1993,15 @@ ExplainNode(PlanState *planstate, List *ancestors, if (es->format == EXPLAIN_FORMAT_TEXT) { + appendStringInfo(es->str, " (actual "); + if (es->timing) - appendStringInfo(es->str, - " (actual time=%.3f..%.3f rows=%.0f loops=%.0f)", - startup_ms, total_ms, rows, nloops); + appendStringInfo(es->str, "time=%.3f..%.3f ", startup_ms, total_ms); + + if (nloops > 1) + appendStringInfo(es->str, "rows=%.2f loops=%.0f)", rows, nloops); else - appendStringInfo(es->str, - " (actual rows=%.0f loops=%.0f)", - rows, nloops); + appendStringInfo(es->str, "rows=%.0f loops=%.0f)", rows, nloops); } else { @@ -2011,8 +2012,16 @@ ExplainNode(PlanState *planstate, List *ancestors, ExplainPropertyFloat("Actual Total Time", "ms", total_ms, 3, es); } - ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es); - ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es); + if (nloops > 1) + { + ExplainPropertyFloat("Actual Rows", NULL, rows, 2, es); + ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es); + } + else + { + ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es); + ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es); + } } } else if (es->analyze) @@ -2064,14 +2073,14 @@ ExplainNode(PlanState *planstate, List *ancestors, if (es->format == EXPLAIN_FORMAT_TEXT) { ExplainIndentText(es); + appendStringInfo(es->str, "actual "); if (es->timing) - appendStringInfo(es->str, - "actual time=%.3f..%.3f rows=%.0f loops=%.0f\n", - startup_ms, total_ms, rows, nloops); + appendStringInfo(es->str, "time=%.3f..%.3f", startup_ms, total_ms); + + if (nloops > 1) + appendStringInfo(es->str, "rows=%.2f loops=%.0f\n", rows, nloops); else - appendStringInfo(es->str, - "actual rows=%.0f loops=%.0f\n", - rows, nloops); + appendStringInfo(es->str, "rows=%.0f loops=%.0f\n", rows, nloops); } else { @@ -2082,8 +2091,17 @@ ExplainNode(PlanState *planstate, List *ancestors, ExplainPropertyFloat("Actual Total Time", "ms", total_ms, 3, es); } - ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es); - ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es); + + if (nloops > 1) + { + ExplainPropertyFloat("Actual Rows", NULL, rows, 2, es); + ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es); + } + else + { + ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es); + ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es); + } } ExplainCloseWorker(n, es); -- cgit v1.2.3