Skip to content

Commit ca5f885

Browse files
committed
Improve eqjoinsel_semi's behavior for small inner relations with no stats.
If we don't have any MCV statistics for the inner relation, and we don't trust its numdistinct estimate either, eqjoinsel_semi falls back to a very conservative estimate (that 50% of the outer rows have matches). This is particularly problematic if the inner relation is completely empty, since then even an explicit ANALYZE won't produce any pg_statistic entries, so there's no way to budge the planner off the bad estimate. We'd produce a better estimate in such cases if we used the nd2/nd1 selectivity heuristic, so an easy fix is to treat the nd2 estimate as non-default if we derive it from clamping to the inner rel's rowcount estimate. This won't fix every related case (mainly because the rowcount estimate might be larger than DEFAULT_NUM_DISTINCT), but it seems like a sane extension of the existing logic, so let's apply the change in HEAD and see if anyone complains. Per bug #14438 from Nikolay Nikitin. Report: https://postgr.es/m/20161128182113.6527.58926@wrigleys.postgresql.org Discussion: https://postgr.es/m/31089.1480384713@sss.pgh.pa.us
1 parent 96fb4c9 commit ca5f885

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

src/backend/utils/adt/selfuncs.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2511,10 +2511,24 @@ eqjoinsel_semi(Oid operator,
25112511
* We can apply this clamping both with respect to the base relation from
25122512
* which the join variable comes (if there is just one), and to the
25132513
* immediate inner input relation of the current join.
2514+
*
2515+
* If we clamp, we can treat nd2 as being a non-default estimate; it's not
2516+
* great, maybe, but it didn't come out of nowhere either. This is most
2517+
* helpful when the inner relation is empty and consequently has no stats.
25142518
*/
25152519
if (vardata2->rel)
2516-
nd2 = Min(nd2, vardata2->rel->rows);
2517-
nd2 = Min(nd2, inner_rel->rows);
2520+
{
2521+
if (nd2 >= vardata2->rel->rows)
2522+
{
2523+
nd2 = vardata2->rel->rows;
2524+
isdefault2 = false;
2525+
}
2526+
}
2527+
if (nd2 >= inner_rel->rows)
2528+
{
2529+
nd2 = inner_rel->rows;
2530+
isdefault2 = false;
2531+
}
25182532

25192533
if (HeapTupleIsValid(vardata1->statsTuple))
25202534
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy