| From: | Richard Guo <guofenglinux(at)gmail(dot)com> |
|---|---|
| To: | wenhui qiu <qiuwenhuifx(at)gmail(dot)com> |
| Cc: | Haibo Yan <tristan(dot)yim(at)gmail(dot)com>, Pg Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Fix CPU cost of right-semi and right-anti hash joins |
| Date: | 2026-08-24 08:18:32 |
| Message-ID: | CAMbWs4-NMxQHhwbYcG5LshirK=57q9S6SX6Cik_a9j+aRb1qBg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Fri, Aug 21, 2026 at 4:55 PM wenhui qiu <qiuwenhuifx(at)gmail(dot)com> wrote:
>> He points out that costing joinrestrictinfo “returns the costs for ALL the quals”, and that after subtracting hash_qual_cost, qp_qual_cost represents all additional clauses beside the hash clauses.
That's true. qp_qual_cost here is the cost of joinqual + otherqual.
>> So in this case qp_qual_cost combines two executor qual classes with different evaluation populations: non-hash joinquals and pushed-down otherquals. It therefore seems that changing the multiplier for the combined qp_qual_cost cannot in general make both parts correct.
>>
>> Would it make sense to split those two costs before applying the right-anti candidate-pair multiplier?
I don't feel much motivated to do that. First, pushed-down quals
that stick at a right anti join are close to nonexistent. Only the
inner side's Vars are visible above the join, and the join nulls
nothing, so a clause that could be placed there normally gets pushed
down further and evaluated below the join. The comment in v4 notes
this tradeoff:
+ * ... (This overcharges
+ * any pushed-down clauses, which are evaluated just once per emitted row,
+ * but such clauses are rare at a right anti join.)
Second, nothing else in the join costing code makes this distinction.
For plain joins, hashjointuples is the count before the joinquals are
applied, so the pushed-down quals are overcharged in the same way.
That's what the existing comment "(This is pessimistic since not all
of the quals may get evaluated at each tuple.)" refers to. JOIN_SEMI
and JOIN_ANTI have the same conflation in the other direction. If we
really want to separate the two classes, it should not be limited to
right anti joins; we'd need to do it for all join types, and that's
beyond the scope of this patch.
- Richard
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Alexandre Felipe | 2026-08-24 08:19:13 | Re: SLOPE - Planner optimizations on monotonic expressions. |
| Previous Message | Alexandre Felipe | 2026-08-24 08:16:28 | Re: [PATCH] bufmgr: tighten LWLock:BufferMapping on InvalidateBuffer |