From 92a43e4857d9682b93c9f755f453cc8fd7c66c81 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 1 May 2017 14:53:42 -0400 Subject: Reduce semijoins with unique inner relations to plain inner joins. If the inner relation can be proven unique, that is it can have no more than one matching row for any row of the outer query, then we might as well implement the semijoin as a plain inner join, allowing substantially more freedom to the planner. This is a form of outer join strength reduction, but it can't be implemented in reduce_outer_joins() because we don't have enough info about the individual relations at that stage. Instead do it much like remove_useless_joins(): once we've built base relations, we can make another pass over the SpecialJoinInfo list and get rid of any entries representing reducible semijoins. This is essentially a followon to the inner-unique patch (commit 9c7f5229a) and makes use of the proof machinery that that patch created. We need only minor refactoring of innerrel_is_unique's API to support this usage. Per performance complaint from Teodor Sigaev. Discussion: https://postgr.es/m/f994fc98-389f-4a46-d1bc-c42e05cb43ed@sigaev.ru --- src/include/optimizer/planmain.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/include/optimizer') diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index 5df68a22a60..e773c0f7eda 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -103,11 +103,12 @@ extern void match_foreign_keys_to_quals(PlannerInfo *root); * prototypes for plan/analyzejoins.c */ extern List *remove_useless_joins(PlannerInfo *root, List *joinlist); +extern void reduce_unique_semijoins(PlannerInfo *root); extern bool query_supports_distinctness(Query *query); extern bool query_is_distinct_for(Query *query, List *colnos, List *opids); extern bool innerrel_is_unique(PlannerInfo *root, - RelOptInfo *outerrel, RelOptInfo *innerrel, - JoinType jointype, List *restrictlist); + Relids outerrelids, RelOptInfo *innerrel, + JoinType jointype, List *restrictlist, bool force_cache); /* * prototypes for plan/setrefs.c -- cgit v1.2.3