Re: Unexpected Seq Scan's when using MERGE WHEN NOT MATCHED BY SOURCE

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: David Mullineux <dmullx(at)gmail(dot)com>
Cc: Feike Steenbergen <feikesteenbergen(at)gmail(dot)com>, pgsql-performance(at)postgresql(dot)org
Subject: Re: Unexpected Seq Scan's when using MERGE WHEN NOT MATCHED BY SOURCE
Date: 2025-01-09 19:39:53
Message-ID: 1903318.1736451593@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-performance

David Mullineux <dmullx(at)gmail(dot)com> writes:
> On Thu, 9 Jan 2025, 12:26 Feike Steenbergen, <feikesteenbergen(at)gmail(dot)com>
> wrote:
>> If we run this however, there is always a Seq Scan against merge_target,
>> whereas the filter of `AND t.device_id = $1` uses a (Bitmap) Index scan
>> in other types of queries.

> I note ,in the documentation, that a Warning box got added which says
> this...
>> If both WHEN NOT MATCHED BY SOURCE and WHEN NOT MATCHED [BY TARGET] clauses
>> are specified, the MERGE command will perform a FULL join between
>> data_source and the target table.

Yeah. That prevents pushing down the join condition, since in a FULL
join all rows of both sides will contribute to the result; none can
be removed ahead of the join.

I may not have fully wrapped my head around this example, but I think
that the fact that "t.device_id = $1" appears in both the ON condition
and the WHEN NOT MATCHED BY SOURCE condition means that only t rows
meeting that condition are of interest, so that in principle we could
optimize by pushing that down to the scan of t. But as you can see,
we don't. Not sure if this pattern is common enough to be worth
trying to implement such an optimization.

regards, tom lane

In response to

Browse pgsql-performance by date

  From Date Subject
Previous Message David Mullineux 2025-01-09 15:52:45 Re: Unexpected Seq Scan's when using MERGE WHEN NOT MATCHED BY SOURCE