On Mon, Sep 28, 2026 at 6:06 PM Matthias van de Meent <[email protected]> wrote: > At Databricks, we noticed a weird plan in one of our TPCC benchmarks > on pg18 (and reproduced on master), which was basically as follows: > > Gather > NestedLoop > NestedLoop > Parallel Seq Scan (Filter: <primary key = constant>) > BitmapScan > BitmapScan > > At face value that plan looks OK, but when you look at it in detail > it's quite a strange plan: The outermost plan is expected to only > produce one row. Joins can generally only produce tuples once rows are > produced on the outer side, so the paralellism is wasted: only a > single worker will find a row, and thus only a single worker will > execute the joins. Given that cap on parallelism, an index scan on > the primary key would've been much cheaper.
I went looking for other reports of this issue. The only really clear example I found was http://postgr.es/m/[email protected] -- in that email, Mark Kirkwood complains of what looks like the exact same problem. In http://postgr.es/m/[email protected] there's an interesting case where the driving table returns only 23 rows, but needs to be joined to a large sequential scan. Note that the *estimate* for the area table is just 1 row, so this is very close to being a case that your patch would affect, but I think that it isn't, quite. http://postgr.es/m/[email protected] is a sort of opposite case: the estimates are high, the actual row counts are low, and parallelism loses, but the issue there may have more to do with worker startup and shutdown being expensive on that machine than with the work distribution being uneven. As far as the approach taken by the patch, I'm not sure that making Path bigger for this is a good idea. It might be fine if we had lots of reports of this being a problem, but it seems expensive as things are. Still, that's not necessarily to say I think we should do nothing. The approach makes me a little nervous in that it treats very small number of rows as a very special case in need of very special handling, but there's some argument to be made that this is actually the case. I mean, small LIMIT values have similar problems, and we get those wrong frequently, arguably because we don't treat that as a sufficiently special case. Still, your patch takes the idea further: the correction drops to zero as soon as #rows >= #workers, but lumpy work distribution could still be an issue past that point (e.g. 5 rows, 4 workers). I'm not really sure what's best here. -- Robert Haas Databricks
