Re: remove_useless_joins vs. bug #19560

From: Richard Guo <guofenglinux(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Thom Brown <thom(at)linux(dot)com>, Jacob Brazeal <jacob(dot)brazeal(at)gmail(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: remove_useless_joins vs. bug #19560
Date: 2026-08-26 07:33:54
Message-ID: CAMbWs4-rxs-GJFNjbRkmArVaeXTXkexpO+vmrXOW9Jg3WxUXWw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, Jul 29, 2026 at 3:21 PM Richard Guo <guofenglinux(at)gmail(dot)com> wrote:
> 4. The commit message claims that "it doesn't seem to result in any
> significant planning-time penalty". I'm somewhat skeptical of that.

I did some testing of planning time. Independent removals are fine,
even faster than before: 64 removable joins that each join directly to
t0 plan in 0.57 ms here vs 1.11 ms on master. They all go in the
first pass, and one extra pass over a single-rel query is cheaper than
the per-removal cleanup the old code did.

Chains of dependent joins are not fine though:

select t0.id from t0
left join t1 on t0.nxt = t1.id
left join t2 on t1.nxt = t2.id
...
left join t64 on t63.nxt = t64.id;

Only t64 can go in the first pass; t63 still looks needed because
attr_needed for t63.nxt includes t64's join, and we only find out
otherwise after the restart. So each link costs a full pass, and this
plans in 20.9 ms vs 1.98 ms on master. The gap widens quickly with
the chain length, and views built on views give the same shape.

I think we can fix this without giving up the restart design. After a
scan has removed something, recompute attr_needed and ph_needed into
temp arrays from the surviving sources (targetlist, the quals in each
rel's baserestrictinfo/joininfo, no-const ECs, PHV expressions,
lateral refs), treating anything whose relids overlap the removed set
as dead, and scan again until nothing more goes. That's basically
rebuild_*_attr_needed() again, but read-only, and it can only
overestimate what's needed, so a mistake just postpones a removal to
the next restart, and the real derived data is never touched.

Thoughts?

- Richard

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Chao Li 2026-08-26 07:37:36 Re: right() returns the whole string for the most negative n
Previous Message shveta malik 2026-08-26 07:06:58 Re: [PATCH] Preserve replication origin OIDs in pg_upgrade