diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 7e2b2e3..b0c7f18 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -105,6 +105,7 @@ typedef struct RI_ConstraintInfo
 	NameData	conname;		/* name of the FK constraint */
 	Oid			pk_relid;		/* referenced relation */
 	Oid			fk_relid;		/* referencing relation */
+	Oid			conparentid;	/* parent constraint */
 	char		confupdtype;	/* foreign key's ON UPDATE action */
 	char		confdeltype;	/* foreign key's ON DELETE action */
 	char		confmatchtype;	/* foreign key's match type */
@@ -221,6 +222,7 @@ static void ri_ReportViolation(const RI_ConstraintInfo *riinfo,
 							   Relation pk_rel, Relation fk_rel,
 							   TupleTableSlot *violatorslot, TupleDesc tupdesc,
 							   int queryno, bool partgone) pg_attribute_noreturn();
+static Oid ri_GetParentConstOid(Oid constraintOid);
 
 
 /*
@@ -1904,8 +1906,12 @@ ri_BuildQueryKey(RI_QueryKey *key, const RI_ConstraintInfo *riinfo,
 	/*
 	 * We assume struct RI_QueryKey contains no padding bytes, else we'd need
 	 * to use memset to clear them.
+	 * If this constraint has conparentid, we use it instead of constraint_id.
+	 * Because constraints which has same conparentid are able to share SPI
+	 * Plan, so this is useful to reduce hashtable size..
 	 */
-	key->constr_id = riinfo->constraint_id;
+	key->constr_id = (riinfo->conparentid == InvalidOid) ?
+				riinfo->constraint_id : ri_GetParentConstOid(riinfo->conparentid);
 	key->constr_queryno = constr_queryno;
 }
 
@@ -2059,6 +2065,7 @@ ri_LoadConstraintInfo(Oid constraintOid)
 	riinfo->confupdtype = conForm->confupdtype;
 	riinfo->confdeltype = conForm->confdeltype;
 	riinfo->confmatchtype = conForm->confmatchtype;
+	riinfo->conparentid = conForm->conparentid;
 
 	DeconstructFkConstraintRow(tup,
 							   &riinfo->nkeys,
@@ -2864,6 +2871,22 @@ ri_HashCompareOp(Oid eq_opr, Oid typeid)
 	return entry;
 }
 
+/*
+ * Find top of parent constraint oid.
+ */
+static Oid
+ri_GetParentConstOid(Oid constraintOid)
+{
+	const RI_ConstraintInfo *riinfo;
+	Oid result;
+
+	riinfo = ri_LoadConstraintInfo(constraintOid);
+
+	result = (riinfo->conparentid == InvalidOid) ?
+		constraintOid :  ri_GetParentConstOid(riinfo->conparentid);
+
+	return result;
+}
 
 /*
  * Given a trigger function OID, determine whether it is an RI trigger,

