diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
new file mode 100644
index 8c9ebe0..e49464c
*** a/src/backend/utils/cache/relcache.c
--- b/src/backend/utils/cache/relcache.c
*************** static long relcacheInvalsReceived = 0L;
*** 136,145 ****
   */
  static List *initFileRelationIds = NIL;
  
! /*
!  * This flag lets us optimize away work in AtEO(Sub)Xact_RelationCache().
   */
! static bool need_eoxact_work = false;
  
  
  /*
--- 136,160 ----
   */
  static List *initFileRelationIds = NIL;
  
! /* 
!  * To avoid the need to inspect the entire hash table in 
!  * AtEO(Sub)Xact_RelationCache(), keep a small list of 
!  * relations that may need work.  If it overflows, then 
!  * revert to inspecting the entire hash table.  If 
!  * n_eoxact_list == -1, then no work can be necessary.
!  * If the same entry shows up in the list more than once,
!  * no harm is done as the processing is idempotent.
   */
! #define MAX_EOXACT_LIST 10
! static Oid eoxact_list[MAX_EOXACT_LIST];
! static int n_eoxact_list=-1;
! 
! #define EOXactListAdd(rel) \
! do { \
! 	if (n_eoxact_list < MAX_EOXACT_LIST) \
! 		if (++n_eoxact_list < MAX_EOXACT_LIST) \
! 			eoxact_list[n_eoxact_list]=rel->rd_id;  \
! } while (0)
  
  
  /*
*************** static void RelationClearRelation(Relati
*** 204,209 ****
--- 219,225 ----
  
  static void RelationReloadIndexInfo(Relation relation);
  static void RelationFlushRelation(Relation relation);
+ static void AtEOXact_release(bool isCommit, RelIdCacheEnt *idhentry);
  static bool load_relcache_init_file(bool shared);
  static void write_relcache_init_file(bool shared);
  static void write_item(const void *data, Size len, FILE *fp);
*************** AtEOXact_RelationCache(bool isCommit)
*** 2246,2269 ****
  	 * To speed up transaction exit, we want to avoid scanning the relcache
  	 * unless there is actually something for this routine to do.  Other than
  	 * the debug-only Assert checks, most transactions don't create any work
! 	 * for us to do here, so we keep a static flag that gets set if there is
  	 * anything to do.	(Currently, this means either a relation is created in
  	 * the current xact, or one is given a new relfilenode, or an index list
! 	 * is forced.)	For simplicity, the flag remains set till end of top-level
  	 * transaction, even though we could clear it at subtransaction end in
! 	 * some cases.
  	 */
! 	if (!need_eoxact_work
  #ifdef USE_ASSERT_CHECKING
  		&& !assert_enabled
  #endif
  		)
- 		return;
- 
- 	hash_seq_init(&status, RelationIdCache);
- 
- 	while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
  	{
  		Relation	relation = idhentry->reldesc;
  
  		/*
--- 2262,2303 ----
  	 * To speed up transaction exit, we want to avoid scanning the relcache
  	 * unless there is actually something for this routine to do.  Other than
  	 * the debug-only Assert checks, most transactions don't create any work
! 	 * for us to do here, so we keep a small static list that gets pushed onto if there is
  	 * anything to do.	(Currently, this means either a relation is created in
  	 * the current xact, or one is given a new relfilenode, or an index list
! 	 * is forced.)	For simplicity, the list remains set till end of top-level
  	 * transaction, even though we could clear it at subtransaction end in
! 	 * some cases, or remove relations from it if they are cleared for other reasons.
  	 */
! 
! 	if (n_eoxact_list < MAX_EOXACT_LIST
  #ifdef USE_ASSERT_CHECKING
  		&& !assert_enabled
  #endif
  		)
  	{
+ 		for ( ; n_eoxact_list>=0; n_eoxact_list--) { 
+ 			idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, 
+ 										 (void *) &(eoxact_list[n_eoxact_list]),
+ 										 HASH_FIND, NULL);
+ 			if (idhentry)
+ 				AtEOXact_release(isCommit, idhentry);
+ 		}
+ 	}
+ 	else 
+ 	{
+ 		hash_seq_init(&status, RelationIdCache);
+ 		while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL)
+ 		{
+ 			AtEOXact_release(isCommit, idhentry);
+ 		}
+ 	}
+ 	n_eoxact_list = -1;
+ }
+ 
+ void 
+ AtEOXact_release(bool isCommit, RelIdCacheEnt *idhentry)
+ {
  		Relation	relation = idhentry->reldesc;
  
  		/*
*************** AtEOXact_RelationCache(bool isCommit)
*** 2301,2307 ****
  			else
  			{
  				RelationClearRelation(relation, false);
! 				continue;
  			}
  		}
  
--- 2335,2341 ----
  			else
  			{
  				RelationClearRelation(relation, false);
! 				return;
  			}
  		}
  
*************** AtEOXact_RelationCache(bool isCommit)
*** 2320,2329 ****
  			relation->rd_oidindex = InvalidOid;
  			relation->rd_indexvalid = 0;
  		}
- 	}
- 
- 	/* Once done with the transaction, we can reset need_eoxact_work */
- 	need_eoxact_work = false;
  }
  
  /*
--- 2354,2359 ----
*************** AtEOSubXact_RelationCache(bool isCommit,
*** 2344,2350 ****
  	 * Skip the relcache scan if nothing to do --- see notes for
  	 * AtEOXact_RelationCache.
  	 */
! 	if (!need_eoxact_work)
  		return;
  
  	hash_seq_init(&status, RelationIdCache);
--- 2374,2380 ----
  	 * Skip the relcache scan if nothing to do --- see notes for
  	 * AtEOXact_RelationCache.
  	 */
! 	if (n_eoxact_list == -1)
  		return;
  
  	hash_seq_init(&status, RelationIdCache);
*************** RelationBuildLocalRelation(const char *r
*** 2482,2489 ****
  	rel->rd_createSubid = GetCurrentSubTransactionId();
  	rel->rd_newRelfilenodeSubid = InvalidSubTransactionId;
  
- 	/* must flag that we have rels created in this transaction */
- 	need_eoxact_work = true;
  
  	/*
  	 * create a new tuple descriptor from the one passed in.  We do this
--- 2512,2517 ----
*************** RelationBuildLocalRelation(const char *r
*** 2568,2575 ****
  	RelationInitPhysicalAddr(rel);
  
  	/*
! 	 * Okay to insert into the relcache hash tables.
  	 */
  	RelationCacheInsert(rel);
  
  	/*
--- 2596,2604 ----
  	RelationInitPhysicalAddr(rel);
  
  	/*
! 	 * Okay to insert into the relcache hash tables.  Must flag that we have rels created in this transaction 
  	 */
+ 	EOXactListAdd(rel);
  	RelationCacheInsert(rel);
  
  	/*
*************** RelationSetNewRelfilenode(Relation relat
*** 2696,2702 ****
  	 */
  	relation->rd_newRelfilenodeSubid = GetCurrentSubTransactionId();
  	/* ... and now we have eoxact cleanup work to do */
! 	need_eoxact_work = true;
  }
  
  
--- 2725,2731 ----
  	 */
  	relation->rd_newRelfilenodeSubid = GetCurrentSubTransactionId();
  	/* ... and now we have eoxact cleanup work to do */
! 	EOXactListAdd(relation);
  }
  
  
*************** RelationSetIndexList(Relation relation,
*** 3469,3475 ****
  	relation->rd_oidindex = oidIndex;
  	relation->rd_indexvalid = 2;	/* mark list as forced */
  	/* must flag that we have a forced index list */
! 	need_eoxact_work = true;
  }
  
  /*
--- 3498,3504 ----
  	relation->rd_oidindex = oidIndex;
  	relation->rd_indexvalid = 2;	/* mark list as forced */
  	/* must flag that we have a forced index list */
! 	EOXactListAdd(relation);
  }
  
  /*
