From 09c9dd39efeae4820b2f6343a5caf4d527bf1603 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 20 Feb 2019 20:53:08 -0500
Subject: [PATCH] Speed up match_eclasses_to_foreign_key_col() when there are
 many ECs.

Check ec_relids before bothering to iterate through the EC members.
On a perhaps extreme, but still real-world, query in which
match_eclasses_to_foreign_key_col() accounts for the bulk of the
planner's runtime, this saves nearly 40% of the runtime.  It's a bit
of a stopgap fix, but it's simple enough to be back-patched to 9.6
where this code came in; so let's do that.

David Rowley

Discussion: https://postgr.es/m/6970.1545327857@sss.pgh.pa.us
---
 src/backend/optimizer/path/equivclass.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 503246f96d..3bfce0389f 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -1963,6 +1963,14 @@ match_eclasses_to_foreign_key_col(PlannerInfo *root,
 			continue;
 		/* Note: it seems okay to match to "broken" eclasses here */
 
+		/*
+		 * If eclass visibly doesn't have members for both rels, there's no
+		 * need to grovel through the members.
+		 */
+		if (!bms_is_member(var1varno, ec->ec_relids) ||
+			!bms_is_member(var2varno, ec->ec_relids))
+			continue;
+
 		foreach(lc2, ec->ec_members)
 		{
 			EquivalenceMember *em = (EquivalenceMember *) lfirst(lc2);
-- 
2.40.0