diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index 1b505a0..f0caa6b 100644
*** a/src/bin/pg_dump/pg_dump_sort.c
--- b/src/bin/pg_dump/pg_dump_sort.c
*************** static void findDependencyLoops(Dumpable
*** 137,142 ****
--- 137,143 ----
  static int findLoop(DumpableObject *obj,
  		 DumpId startPoint,
  		 bool *processed,
+ 		 DumpId *searchFailed,
  		 DumpableObject **workspace,
  		 int depth);
  static void repairDependencyLoop(DumpableObject **loop,
*************** static void
*** 633,653 ****
  findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs)
  {
  	/*
! 	 * We use two data structures here.  One is a bool array processed[],
! 	 * which is indexed by dump ID and marks the objects already processed
! 	 * during this invocation of findDependencyLoops().  The other is a
! 	 * workspace[] array of DumpableObject pointers, in which we try to build
! 	 * lists of objects constituting loops.  We make workspace[] large enough
! 	 * to hold all the objects, which is huge overkill in most cases but could
! 	 * theoretically be necessary if there is a single dependency chain
! 	 * linking all the objects.
  	 */
  	bool	   *processed;
  	DumpableObject **workspace;
  	bool		fixedloop;
  	int			i;
  
  	processed = (bool *) pg_malloc0((getMaxDumpId() + 1) * sizeof(bool));
  	workspace = (DumpableObject **) pg_malloc(totObjs * sizeof(DumpableObject *));
  	fixedloop = false;
  
--- 634,668 ----
  findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs)
  {
  	/*
! 	 * We use three data structures here:
! 	 *
! 	 * processed[] is a bool array indexed by dump ID, marking the objects
! 	 * already processed during this invocation of findDependencyLoops().
! 	 *
! 	 * searchFailed[] is another array indexed by dump ID.  searchFailed[j] is
! 	 * set to dump ID k if we have proven that there is no dependency path
! 	 * leading from object j back to start point k.  This allows us to skip
! 	 * useless searching when there are multiple dependency paths from k to j,
! 	 * which is a common situation.  We could use a simple bool array for
! 	 * this, but then we'd need to re-zero it for each start point, resulting
! 	 * in O(N^2) zeroing work.  Using the start point's dump ID as the "true"
! 	 * value lets us skip clearing the array before we consider the next start
! 	 * point.
! 	 *
! 	 * workspace[] is an array of DumpableObject pointers, in which we try to
! 	 * build lists of objects constituting loops.  We make workspace[] large
! 	 * enough to hold all the objects in TopoSort's output, which is huge
! 	 * overkill in most cases but could theoretically be necessary if there is
! 	 * a single dependency chain linking all the objects.
  	 */
  	bool	   *processed;
+ 	DumpId	   *searchFailed;
  	DumpableObject **workspace;
  	bool		fixedloop;
  	int			i;
  
  	processed = (bool *) pg_malloc0((getMaxDumpId() + 1) * sizeof(bool));
+ 	searchFailed = (DumpId *) pg_malloc0((getMaxDumpId() + 1) * sizeof(DumpId));
  	workspace = (DumpableObject **) pg_malloc(totObjs * sizeof(DumpableObject *));
  	fixedloop = false;
  
*************** findDependencyLoops(DumpableObject **obj
*** 657,663 ****
  		int			looplen;
  		int			j;
  
! 		looplen = findLoop(obj, obj->dumpId, processed, workspace, 0);
  
  		if (looplen > 0)
  		{
--- 672,683 ----
  		int			looplen;
  		int			j;
  
! 		looplen = findLoop(obj,
! 						   obj->dumpId,
! 						   processed,
! 						   searchFailed,
! 						   workspace,
! 						   0);
  
  		if (looplen > 0)
  		{
*************** findDependencyLoops(DumpableObject **obj
*** 685,690 ****
--- 705,711 ----
  		exit_horribly(modulename, "could not identify dependency loop\n");
  
  	free(workspace);
+ 	free(searchFailed);
  	free(processed);
  }
  
*************** findDependencyLoops(DumpableObject **obj
*** 695,700 ****
--- 716,722 ----
   *	obj: object we are examining now
   *	startPoint: dumpId of starting object for the hoped-for circular loop
   *	processed[]: flag array marking already-processed objects
+  *	searchFailed[]: flag array marking already-unsuccessfully-visited objects
   *	workspace[]: work array in which we are building list of loop members
   *	depth: number of valid entries in workspace[] at call
   *
*************** static int
*** 708,713 ****
--- 730,736 ----
  findLoop(DumpableObject *obj,
  		 DumpId startPoint,
  		 bool *processed,
+ 		 DumpId *searchFailed,
  		 DumpableObject **workspace,
  		 int depth)
  {
*************** findLoop(DumpableObject *obj,
*** 721,726 ****
--- 744,756 ----
  		return 0;
  
  	/*
+ 	 * If we've already proven there is no path from this object back to the
+ 	 * startPoint, forget it.
+ 	 */
+ 	if (searchFailed[obj->dumpId] == startPoint)
+ 		return 0;
+ 
+ 	/*
  	 * Reject if obj is already present in workspace.  This test prevents us
  	 * from going into infinite recursion if we are given a startPoint object
  	 * that links to a cycle it's not a member of, and it guarantees that we
*************** findLoop(DumpableObject *obj,
*** 759,770 ****
--- 789,806 ----
  		newDepth = findLoop(nextobj,
  							startPoint,
  							processed,
+ 							searchFailed,
  							workspace,
  							depth);
  		if (newDepth > 0)
  			return newDepth;
  	}
  
+ 	/*
+ 	 * Remember there is no path from here back to startPoint
+ 	 */
+ 	searchFailed[obj->dumpId] = startPoint;
+ 
  	return 0;
  }
  
