diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index aa5b97f..ec74b60 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -153,6 +153,9 @@ static int	default_freeze_table_age;
 static int	default_multixact_freeze_min_age;
 static int	default_multixact_freeze_table_age;
 
+/* Counter to determine if statistics should be refreshed */
+static bool use_existing_stats = false;
+
 /* Memory context for long-lived data */
 static MemoryContext AutovacMemCxt;
 
@@ -2803,18 +2806,68 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 	bool		wraparound;
 	AutoVacOpts *avopts;
 
-	/* use fresh stats */
-	autovac_refresh_stats();
-
-	shared = pgstat_fetch_stat_dbentry(InvalidOid);
-	dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId);
-
 	/* fetch the relation's relcache entry */
 	classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
 	if (!HeapTupleIsValid(classTup))
 		return NULL;
 	classForm = (Form_pg_class) GETSTRUCT(classTup);
 
+	/* 
+	 * Before stats refresh, check existing stats for avoiding
+ 	 * frequent reloading of pgstats.
+ 	 * In the case of very large numbers of tables, the cost of re-reading
+ 	 * the stats file can be significant, and the frequent calls to 
+ 	 * autovac_refresh_stats() can make certain autovacuum workers unable to work.
+ 	 * So if the last time we checked a table that was already vacuumed after 
+ 	 * refres stats, check the current statistics before refreshing it.
+	 */
+	if (use_existing_stats)
+	{
+		shared = pgstat_fetch_stat_dbentry(InvalidOid);
+		dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId);
+
+		/*
+	 	 * Get the applicable reloptions.  If it is a TOAST table, try to get the
+	 	 * main table reloptions if the toast table itself doesn't have.
+	 	 */
+		avopts = extract_autovac_opts(classTup, pg_class_desc);
+		if (classForm->relkind == RELKIND_TOASTVALUE &&
+			avopts == NULL && table_toast_map != NULL)
+		{
+			av_relation *hentry;
+			bool		found;
+
+			hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
+			if (found && hentry->ar_hasrelopts)
+			avopts = &hentry->ar_reloptions;
+		}
+
+		/* fetch the pgstat table entry */
+		tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
+											 shared, dbentry);
+
+		relation_needs_vacanalyze(relid, avopts, classForm, tabentry,
+								  effective_multixact_freeze_max_age,
+								  &dovacuum, &doanalyze, &wraparound);
+
+		/* ignore ANALYZE for toast tables */
+		if (classForm->relkind == RELKIND_TOASTVALUE)
+			doanalyze = false;
+
+		/* someone has already issued vacuum, so exit quickly */
+		if (!doanalyze && !dovacuum)
+		{
+			heap_freetuple(classTup);
+			return NULL;
+		}
+	}
+
+	/* use fresh stats and recheck again */
+	autovac_refresh_stats();
+
+	shared = pgstat_fetch_stat_dbentry(InvalidOid);
+	dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId);
+
 	/*
 	 * Get the applicable reloptions.  If it is a TOAST table, try to get the
 	 * main table reloptions if the toast table itself doesn't have.
@@ -2929,9 +2982,18 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 		tab->at_dobalance =
 			!(avopts && (avopts->vacuum_cost_limit > 0 ||
 						 avopts->vacuum_cost_delay > 0));
+
+		/* We might be better to refresh stats */
+		use_existing_stats = false;
 	}
+	else
+	{
 
-	heap_freetuple(classTup);
+		heap_freetuple(classTup);
+
+		/* The relid has already vacuumed, so we might be better to use existing stats */
+		use_existing_stats = true;
+	}
 
 	return tab;
 }
