public inbox for [email protected]  
help / color / mirror / Atom feed
From: Ilia Evdokimov <[email protected]>
To: Daniel Gustafsson <[email protected]>
To: Ibrar Ahmed <[email protected]>
Cc: Gregory Stark (as CFM) <[email protected]>
Cc: Tom Lane <[email protected]>
Cc: Robert Haas <[email protected]>
Cc: Amit Kapila <[email protected]>
Cc: Justin Pryzby <[email protected]>
Cc: Peter Geoghegan <[email protected]>
Cc: vignesh C <[email protected]>
Cc: David G. Johnston <[email protected]>
Cc: [email protected]
Subject: Re: explain analyze rows=%.0f
Date: Thu, 12 Dec 2024 14:56:47 +0300
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <CA+TgmoZv8DvmeQHQAX+rkn68id2N+DoUhFZB36d-_w1tyAeqeA@mail.gmail.com>
	<[email protected]>
	<CAA4eK1Lmo0FX6Nfr_k3-UX1Hpei1H-xPHL6Wwx7SLUP3s+O1mA@mail.gmail.com>
	<CA+Tgmob0BBeK6GEMUQBPiv0kJpTJSEgX+OUD2FeY42zWVgJuLw@mail.gmail.com>
	<[email protected]>
	<CALtqXTfM3GJbFsB63ajfHcYvFhUA0ySX4f4MVS3Dau2vopU+Rw@mail.gmail.com>
	<CAM-w4HNLRO8QJvF3x13wjjdkJHobORxaKrcuyF1cKaTiXuvDbA@mail.gmail.com>
	<CALtqXTcZE6YW=m9ZmNU6sRJ+RTC15NFc__foP1S2KaWvGOf6JA@mail.gmail.com>
	<[email protected]>
	<[email protected]>


On 01.08.2023 23:29, Daniel Gustafsson wrote:
>> On 3 Jul 2023, at 18:34, Daniel Gustafsson <[email protected]> wrote:
>>
>>> On 8 Jun 2023, at 19:49, Ibrar Ahmed <[email protected]> wrote:
>>> On Mon, Mar 20, 2023 at 7:56 PM Gregory Stark (as CFM) <[email protected] <mailto:[email protected]>> wrote:
>>> This patch was marked Returned with Feedback and then later Waiting on
>>> Author. And it hasn't had any updates since January. What is the state
>>> on this feedback? If it's already done we can set the patch to Ready
>>> for Commit and if not do you disagree with the proposed changes?
>>>
>>> If there is a consensus to modify the test cases' output, I am willing to
>>> make the necessary changes and adjust the patch accordingly. However,
>>> if there is a preference to keep the output of certain test cases unchanged,
>>> I can rebase and modify the patch accordingly to accommodate those preferences.
>> As there hasn't been any other comments I suggest updating your patch to
>> address Tom's comments to see if we can make progress here.
> Since there hasn't been any updates here, and the thread has been stalled, I'm
> marking this returned with feedback.  Please feel free to resubmit a version of
> the patch addressing comments to a future CF.
>
> --
> Daniel Gustafsson
>
>
>

Hi everybody,

When the total number of returned tuples is less than the number of 
loops currently shows 'rows = 0'. This can mislead users into thinking 
that no rows were returned at all, even though some might have appeared 
occasionally. For example, if there is 1 tuple over 100 loops, the 
average is 0.01 rows per loop, but as displayed it simply looks like zero.

To clarify this situation, it has been suggested that display rows with 
two decimal places in scenarios where 'loops > 1 && ntuples < loops'. In 
other words, show something like 'rows = 0.01' instead of 'rows=0'. This 
minor change would make it evident that rows did occur, just very 
infrequently.

For all other cases, the current formatting would remain the same. This 
approach aims to provide a more nuanced understanding of query execution 
behavior without introducing unnecessary complexity or false precision.

I would appreciate any thoughts or feedback on this proposal.

--
Best regards,
Ilia Evdokimov,
Tantor Labs LLC.


Attachments:

  [text/x-patch] explain_float_row_v4.patch (4.4K, ../[email protected]/2-explain_float_row_v4.patch)
  download | inline diff:
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index a201ed3082..b3f7fa8743 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -1981,14 +1981,14 @@ 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 && planstate->instrument->ntuples < nloops)
+				appendStringInfo(es->str," rows=%.2f loops=%.2f)", rows, nloops);
 			else
-				appendStringInfo(es->str,
-								 " (actual rows=%.0f loops=%.0f)",
-								 rows, nloops);
+				appendStringInfo(es->str," rows=%.0f loops=%.0f)", rows, nloops);
 		}
 		else
 		{
@@ -1999,8 +1999,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 && planstate->instrument->ntuples < nloops)
+			{
+				ExplainPropertyFloat("Actual Rows", NULL, rows, 2, es);
+				ExplainPropertyFloat("Actual Loops", NULL, nloops, 2, es);
+			}
+			else
+			{
+				ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es);
+				ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es);
+			}
 		}
 	}
 	else if (es->analyze)
@@ -2052,14 +2060,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 && planstate->instrument->ntuples < nloops)
+					appendStringInfo(es->str," rows=%.2f loops=%.2f)", rows, nloops);
 				else
-					appendStringInfo(es->str,
-									 "actual rows=%.0f loops=%.0f\n",
-									 rows, nloops);
+					appendStringInfo(es->str," rows=%.0f loops=%.0f)", rows, nloops);
 			}
 			else
 			{
@@ -2070,8 +2078,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 && planstate->instrument->ntuples < nloops)
+				{
+					ExplainPropertyFloat("Actual Rows", NULL, rows, 2, es);
+					ExplainPropertyFloat("Actual Loops", NULL, nloops, 2, es);
+				}
+				else
+				{
+					ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es);
+					ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es);
+				}
 			}
 
 			ExplainCloseWorker(n, es);
diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out
index c52bc40e81..cf50776ef7 100644
--- a/src/test/regress/expected/partition_prune.out
+++ b/src/test/regress/expected/partition_prune.out
@@ -3041,16 +3041,16 @@ select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
 
 explain (analyze, costs off, summary off, timing off, buffers off)
 select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1;
-                                QUERY PLAN                                
---------------------------------------------------------------------------
+                                   QUERY PLAN                                   
+--------------------------------------------------------------------------------
  Nested Loop (actual rows=3 loops=1)
    ->  Seq Scan on tbl1 (actual rows=5 loops=1)
-   ->  Append (actual rows=1 loops=5)
+   ->  Append (actual rows=0.60 loops=5.00)
          ->  Index Scan using tprt1_idx on tprt_1 (never executed)
                Index Cond: (col1 = tbl1.col1)
          ->  Index Scan using tprt2_idx on tprt_2 (actual rows=1 loops=2)
                Index Cond: (col1 = tbl1.col1)
-         ->  Index Scan using tprt3_idx on tprt_3 (actual rows=0 loops=3)
+         ->  Index Scan using tprt3_idx on tprt_3 (actual rows=0.33 loops=3.00)
                Index Cond: (col1 = tbl1.col1)
          ->  Index Scan using tprt4_idx on tprt_4 (never executed)
                Index Cond: (col1 = tbl1.col1)


view thread (9+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: explain analyze rows=%.0f
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox