diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 5d23a3f7d4..c242c706f4 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -24,6 +24,7 @@ #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" +#include "utils/selfuncs.h" #include "utils/typcache.h" /* Hook for plugins to get control in add_paths_to_joinrel() */ @@ -1675,14 +1676,8 @@ match_unsorted_outer(PlannerInfo *root, { Path *innerpath = (Path *) lfirst(lc2); Path *rcpath; - - try_nestloop_path(root, - joinrel, - outerpath, - innerpath, - merge_pathkeys, - jointype, - extra); + EstimationInfo estinfo; + double estgroups; /* * Try generating a result cache path and see if that makes the @@ -1691,14 +1686,41 @@ match_unsorted_outer(PlannerInfo *root, rcpath = get_resultcache_path(root, innerrel, outerrel, innerpath, outerpath, jointype, extra); - if (rcpath != NULL) + + if (rcpath == NULL) try_nestloop_path(root, joinrel, outerpath, - rcpath, + innerpath, merge_pathkeys, jointype, extra); + else + { + estgroups = estimate_num_groups(root, + ((ResultCachePath *) rcpath)->param_exprs, + outerpath->rows, + NULL, + &estinfo); + + if (rcpath != NULL && estgroups < outerpath->rows / 2.0 && + (estinfo.flags & SELFLAG_USED_DEFAULT) == 0) + try_nestloop_path(root, + joinrel, + outerpath, + rcpath, + merge_pathkeys, + jointype, + extra); + else + try_nestloop_path(root, + joinrel, + outerpath, + innerpath, + merge_pathkeys, + jointype, + extra); + } } /* Also consider materialized form of the cheapest inner path */