diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index aa5b97f..4ebe45f 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -325,6 +325,10 @@ static void autovac_balance_cost(void);
 static void do_autovacuum(void);
 static void FreeWorkerInfo(int code, Datum arg);
 
+static void recheck_relation_needs_vacanalyze(Oid relid, Form_pg_class classForm,
+							 AutoVacOpts *avopts,
+							 int effective_multixact_freeze_max_age,
+							 bool *dovacuum, bool *doanalyze, bool *wraparound);
 static autovac_table *table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 											TupleDesc pg_class_desc,
 											int effective_multixact_freeze_max_age);
@@ -2780,6 +2784,38 @@ get_pgstat_tabentry_relid(Oid relid, bool isshared, PgStat_StatDBEntry *shared,
 }
 
 /*
+ * Subroutine of table_recheck_autovac.
+ */
+static void
+recheck_relation_needs_vacanalyze(Oid relid,
+							   Form_pg_class classForm,
+							   AutoVacOpts *avopts,
+							   int effective_multixact_freeze_max_age,
+							   bool *dovacuum,
+							   bool *doanalyze,
+							   bool *wraparound)
+{
+	PgStat_StatTabEntry *tabentry;
+	PgStat_StatDBEntry *shared;
+	PgStat_StatDBEntry *dbentry;
+
+	shared = pgstat_fetch_stat_dbentry(InvalidOid);
+	dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId);
+
+	/* 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;
+}
+
+/*
  * table_recheck_autovac
  *
  * Recheck whether a table still needs vacuum or analyze.  Return value is a
@@ -2797,17 +2833,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 	bool		dovacuum;
 	bool		doanalyze;
 	autovac_table *tab = NULL;
-	PgStat_StatTabEntry *tabentry;
-	PgStat_StatDBEntry *shared;
-	PgStat_StatDBEntry *dbentry;
 	bool		wraparound;
 	AutoVacOpts *avopts;
-
-	/* use fresh stats */
-	autovac_refresh_stats();
-
-	shared = pgstat_fetch_stat_dbentry(InvalidOid);
-	dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId);
+	static bool use_existing_stats = false;
 
 	/* fetch the relation's relcache entry */
 	classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
@@ -2831,17 +2859,35 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 			avopts = &hentry->ar_reloptions;
 	}
 
-	/* fetch the pgstat table entry */
-	tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
-										 shared, dbentry);
+	/*
+	 * 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
+	 * refresh stats, check the current statistics before refreshing it.
+	 */
+	if (use_existing_stats)
+	{
+		recheck_relation_needs_vacanalyze(relid, classForm, avopts,
+									   effective_multixact_freeze_max_age,
+									   &dovacuum, &doanalyze, &wraparound);
 
-	relation_needs_vacanalyze(relid, avopts, classForm, tabentry,
-							  effective_multixact_freeze_max_age,
-							  &dovacuum, &doanalyze, &wraparound);
+		/* someone has already issued vacuum, so exit quickly */
+		if (!doanalyze && !dovacuum)
+		{
+			heap_freetuple(classTup);
+			return NULL;
+		}
+	}
 
-	/* ignore ANALYZE for toast tables */
-	if (classForm->relkind == RELKIND_TOASTVALUE)
-		doanalyze = false;
+	/* use fresh stats and recheck again */
+	autovac_refresh_stats();
+
+	recheck_relation_needs_vacanalyze(relid, classForm, avopts,
+								   effective_multixact_freeze_max_age,
+								   &dovacuum, &doanalyze, &wraparound);
 
 	/* OK, it needs something done */
 	if (doanalyze || dovacuum)
@@ -2929,10 +2975,27 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 		tab->at_dobalance =
 			!(avopts && (avopts->vacuum_cost_limit > 0 ||
 						 avopts->vacuum_cost_delay > 0));
+
+		/*
+		 * The relid had not yet been vacuumed. That means, it is unlikely that the
+		 * stats that this worker currently has are updated by other worker's.
+		 * So we might be better to refresh the stats in the next this recheck.
+		 */
+		use_existing_stats = false;
+	}
+	else
+	{
+		/*
+		 * The relid had already vacuumed. That means, that for the stats that this
+		 * worker currently has, the info of tables that this worker will process may
+		 * have been updated by other workers with information that has already been
+		 * vacuumed or analyzed.
+		 * So we might be better to reuse the existing stats in the next this recheck.
+		 */
+		use_existing_stats = true;
 	}
 
 	heap_freetuple(classTup);
-
 	return tab;
 }
 
