| From: | David Rowley <dgrowleyml(at)gmail(dot)com> |
|---|---|
| To: | Tatsuya Kawata <kawatatatsuya0913(at)gmail(dot)com> |
| Cc: | Yash Jadhav <yash(dot)jadhav8008(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: [PATCH] Add memory/disk usage for Function Scan nodes in EXPLAIN |
| Date: | 2026-10-15 01:24:57 |
| Message-ID: | CAApHDvqj+_5kK+uF5qosD0m+8zkhubyaXGSntpsKLvyrLkM3tQ@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Wed, 14 Oct 2026 at 03:38, Tatsuya Kawata
<kawatatatsuya0913(at)gmail(dot)com> wrote:
> - I changed how the statistics are kept, so that the workers and EXPLAIN
> use the same values. The tuplestore returned by
> ExecMakeTableFunctionResult() already holds the whole result set of
> the function and doesn't grow after that, so its statistics are taken
> right after it's returned, and used to update the per-function maximum
> and the node-level values. EXPLAIN just reads the leader's values, and
> each worker copies its own into shared memory when it ends.
I don't think reporting the sum of the maximum space used by each
function is an accurate way to report the storage space used. I
believe what we should be showing is the "high water mark" of *total
storage* used per rescan, not the sum of high water marks per
function. With what you have, we could report a storage amount that
was never used by the Function Scan at any single moment in time.
To look at it another way: if you have two bank accounts with ¥1000 in
one and ¥0 in the other. If today you transfer the ¥1000 into the
account with ¥0, would you report your total net worth as the sum of
the maximum balance of the accounts on that day? Surely the answer is
¥1000 and not ¥2000, as at no point in time in this scenario did you
have ¥2000.
Effectively, the patch is reporting the ¥2000 scenario:
explain (analyze, costs off, timing off, summary off) select * from
(values(1),(2000)) v(i), lateral (select * from rows from
(generate_series(1, v.i), generate_series(2000, v.i, -1)));
Nested Loop (actual rows=4000.00 loops=1)
-> Values Scan on "*VALUES*" (actual rows=2.00 loops=1)
-> Function Scan on generate_series (actual rows=2000.00 loops=2)
Storage: Memory Maximum Storage: 189kB
In each rescan there's a function with a 1-row series and the other
has a 2000-row series. The patch is reporting the memory used by 4000
rows instead of 2001 rows.
I'd expect to see this report 112kB, effectively 17kB + 95kB per:
explain (analyze, costs off, timing off, summary off) select * from
generate_Series(1,2000);
Function Scan on generate_series (actual rows=2000.00 loops=1)
Storage: Memory Maximum Storage: 95kB
explain (analyze, costs off, timing off, summary off) select * from
generate_Series(2000,2000,-1);
Function Scan on generate_series (actual rows=1.00 loops=1)
Storage: Memory Maximum Storage: 17kB
David
| From | Date | Subject | |
|---|---|---|---|
| Previous Message | Fujii Masao | 2026-10-15 01:13:51 | Re: [PATCH] Report no unpinned buffers as insufficient resources |