Re: Partial hash index is not used for implied qual.

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: David Rowley <dgrowleyml(at)gmail(dot)com>
Cc: Sergei Glukhov <s(dot)glukhov(at)postgrespro(dot)ru>, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Partial hash index is not used for implied qual.
Date: 2025-11-26 18:25:57
Message-ID: 1615744.1764181557@sss.pgh.pa.us
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

David Rowley <dgrowleyml(at)gmail(dot)com> writes:
> On Tue, 25 Nov 2025 at 15:01, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>> Actually, after thinking a bit longer, it'd be better to do something
>> like the attached so that we don't keep redundant quals unless they'd
>> *all* be excluded.

> I think your 1st patch was more along the correct lines. With the 2nd
> one, I think you're maybe assuming that the non-empty newrestrictinfo
> must contain an indexable qual, but the list we're working with at
> that point is the rel's baserestrictinfo, which could contain a bunch
> of stuff that'll never match to the index. If you continue to remove
> the implied qual when there's a non-indexable base qual in the list,
> then we'll still have the same issue that Sergei is trying to fix.

Right, as Sergei also noted. We should just do it as attached.

I checked the costing calculations and it's basically that
genericcostestimate doesn't understand about hash buckets.
For the partial index, it correctly estimates that we'll visit
all 10 of the tuples in the index, so it supposes that that
means we'll visit all of the index's pages. For the non-partial
index, it correctly estimates that we'll visit 10 of the 1000
tuples in the index, so it supposes that that means we'll visit
1/100th of the index's pages (rounded up to 1). This error is
compounded by the toy example, which only has 6 pages in either index
(the minimum size of a hash index, I think). There may or may not be
anything we can usefully do to improve that situation ... and for that
matter, it's not clear that preferring the partial index would really
be a win. As constructed, this test case has only one hash value in
the partial index, which I think is not exactly a case where you want
a hash index. I tried scaling up the table size, and got a badly
bloated partial index (about half as big as the non-partial one),
which seems to indicate that the code is vainly splitting and
re-splitting trying to divide that one huge bucket.

So I'm inclined to apply the attached and just call it good.

Should we back-patch? I'm unsure. Clearly it's a bug that we
cannot generate an indexscan plan in this case, but we've learned
that changing plans in released branches is often not wanted.
And given the lack of field complaints, nobody is using the case
anyway.

regards, tom lane

Attachment Content-Type Size
v2-fix-partial-hash-index-scan.patch text/x-diff 873 bytes

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tomas Vondra 2025-11-26 18:30:38 Re: should we have a fast-path planning for OLTP starjoins?
Previous Message Michael Banck 2025-11-26 17:41:39 Re: [PATCH] Expose checkpoint timestamp and duration in pg_stat_checkpointer