0001-Add-child-EC-members-for-only-the-non-dummy-children.patch

text/plain

Filename: 0001-Add-child-EC-members-for-only-the-non-dummy-children.patch
Type: text/plain
Part: 0
Message: Re: Query with high planning time at version 11.1 compared versions 10.5 and 11.0

Patch

Format: format-patch
Series: patch 0001
Subject: Add child EC members for only the non-dummy children
File+
src/backend/optimizer/path/allpaths.c 12 15
src/backend/optimizer/path/joinrels.c 19 0
From 67d051526138b00b7429996655a403535ea6d75c Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Thu, 6 Dec 2018 10:38:25 +0900
Subject: [PATCH] Add child EC members for only the non-dummy children

In set_append_rel_size, child EC members are added before checking
if the child relation itself is dummy.  That's very inefficient if
there are lots of children as the EC lists grow huge.  Such EC
members would remain unused unless the child participates in
partitionwise join, so add them only if the child "actually"
participates in partitionwise join.
---
 src/backend/optimizer/path/allpaths.c | 27 ++++++++++++---------------
 src/backend/optimizer/path/joinrels.c | 19 +++++++++++++++++++
 2 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 738bb30848..2b5fef2233 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -1034,21 +1034,6 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
 								   1, &appinfo);
 
 		/*
-		 * We have to make child entries in the EquivalenceClass data
-		 * structures as well.  This is needed either if the parent
-		 * participates in some eclass joins (because we will want to consider
-		 * inner-indexscan joins on the individual children) or if the parent
-		 * has useful pathkeys (because we should try to build MergeAppend
-		 * paths that produce those sort orderings). Even if this child is
-		 * deemed dummy, it may fall on nullable side in a child-join, which
-		 * in turn may participate in a MergeAppend, where we will need the
-		 * EquivalenceClass data structures.
-		 */
-		if (rel->has_eclass_joins || has_useful_pathkeys(root, rel))
-			add_child_rel_equivalences(root, appinfo, rel, childrel);
-		childrel->has_eclass_joins = rel->has_eclass_joins;
-
-		/*
 		 * We have to copy the parent's quals to the child, with appropriate
 		 * substitution of variables.  However, only the baserestrictinfo
 		 * quals are needed before we can check for constraint exclusion; so
@@ -1186,6 +1171,18 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
 			continue;
 		}
 
+		/*
+		 * We have to make child entries in the EquivalenceClass data
+		 * structures as well.  This is needed either if the parent
+		 * participates in some eclass joins (because we will want to consider
+		 * inner-indexscan joins on the individual children) or if the parent
+		 * has useful pathkeys (because we should try to build MergeAppend
+		 * paths that produce those sort orderings).
+		 */
+		if (rel->has_eclass_joins || has_useful_pathkeys(root, rel))
+			add_child_rel_equivalences(root, appinfo, rel, childrel);
+		childrel->has_eclass_joins = rel->has_eclass_joins;
+
 		/* CE failed, so finish copying/modifying join quals. */
 		childrel->joininfo = (List *)
 			adjust_appendrel_attrs(root,
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index d3d21fed5d..631468491c 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -1376,6 +1376,25 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
 		AppendRelInfo **appinfos;
 		int			nappinfos;
 
+		/*
+		 * set_append_rel_size() doesn't add EC members for dummy child
+		 * relations.  Do that now, because downstream code relies on child
+		 * EC members having been added.
+		 */
+		if (IS_SIMPLE_REL(child_rel1) && IS_DUMMY_REL(child_rel1))
+		{
+			AppendRelInfo *appinfo = root->append_rel_array[child_rel1->relid];
+
+			add_child_rel_equivalences(root, appinfo, rel1, child_rel1);
+		}
+
+		if (IS_SIMPLE_REL(child_rel2) && IS_DUMMY_REL(child_rel2))
+		{
+			AppendRelInfo *appinfo = root->append_rel_array[child_rel2->relid];
+
+			add_child_rel_equivalences(root, appinfo, rel2, child_rel2);
+		}
+
 		/* We should never try to join two overlapping sets of rels. */
 		Assert(!bms_overlap(child_rel1->relids, child_rel2->relids));
 		child_joinrelids = bms_union(child_rel1->relids, child_rel2->relids);
-- 
2.11.0