From 4e0b63b0b9e705a4e819c79c1e42bc35fb86812d Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 8 Dec 2008 15:44:54 +0000
Subject: [PATCH] Teach pgstat_vacuum_stat to not bother scanning pg_proc in
 the common case where no function stats entries exist.  Partial response to
 Pavel's observation that small VACUUM operations are noticeably slower in CVS
 HEAD than 8.3.

---
 src/backend/postmaster/pgstat.c | 71 ++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 33 deletions(-)

diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 85c4313cca3..0526d169f7e 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -13,7 +13,7 @@
  *
  *	Copyright (c) 2001-2008, PostgreSQL Global Development Group
  *
- *	$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.184 2008/11/04 11:04:06 petere Exp $
+ *	$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.185 2008/12/08 15:44:54 tgl Exp $
  * ----------
  */
 #include "postgres.h"
@@ -967,55 +967,60 @@ pgstat_vacuum_stat(void)
 	hash_destroy(htab);
 
 	/*
-	 * Now repeat the above steps for functions.
+	 * Now repeat the above steps for functions.  However, we needn't bother
+	 * in the common case where no function stats are being collected.
 	 */
-	htab = pgstat_collect_oids(ProcedureRelationId);
+	if (dbentry->functions != NULL &&
+		hash_get_num_entries(dbentry->functions) > 0)
+	{
+		htab = pgstat_collect_oids(ProcedureRelationId);
 
-	pgstat_setheader(&f_msg.m_hdr, PGSTAT_MTYPE_FUNCPURGE);
-	f_msg.m_databaseid = MyDatabaseId;
-	f_msg.m_nentries = 0;
+		pgstat_setheader(&f_msg.m_hdr, PGSTAT_MTYPE_FUNCPURGE);
+		f_msg.m_databaseid = MyDatabaseId;
+		f_msg.m_nentries = 0;
 
-	hash_seq_init(&hstat, dbentry->functions);
-	while ((funcentry = (PgStat_StatFuncEntry *) hash_seq_search(&hstat)) != NULL)
-	{
-		Oid			funcid = funcentry->functionid;
+		hash_seq_init(&hstat, dbentry->functions);
+		while ((funcentry = (PgStat_StatFuncEntry *) hash_seq_search(&hstat)) != NULL)
+		{
+			Oid			funcid = funcentry->functionid;
 
-		CHECK_FOR_INTERRUPTS();
+			CHECK_FOR_INTERRUPTS();
 
-		if (hash_search(htab, (void *) &funcid, HASH_FIND, NULL) != NULL)
-			continue;
+			if (hash_search(htab, (void *) &funcid, HASH_FIND, NULL) != NULL)
+				continue;
 
-		/*
-		 * Not there, so add this function's Oid to the message
-		 */
-		f_msg.m_functionid[f_msg.m_nentries++] = funcid;
+			/*
+			 * Not there, so add this function's Oid to the message
+			 */
+			f_msg.m_functionid[f_msg.m_nentries++] = funcid;
+
+			/*
+			 * If the message is full, send it out and reinitialize to empty
+			 */
+			if (f_msg.m_nentries >= PGSTAT_NUM_FUNCPURGE)
+			{
+				len = offsetof(PgStat_MsgFuncpurge, m_functionid[0])
+					+f_msg.m_nentries * sizeof(Oid);
+
+				pgstat_send(&f_msg, len);
+
+				f_msg.m_nentries = 0;
+			}
+		}
 
 		/*
-		 * If the message is full, send it out and reinitialize to empty
+		 * Send the rest
 		 */
-		if (f_msg.m_nentries >= PGSTAT_NUM_FUNCPURGE)
+		if (f_msg.m_nentries > 0)
 		{
 			len = offsetof(PgStat_MsgFuncpurge, m_functionid[0])
 				+f_msg.m_nentries * sizeof(Oid);
 
 			pgstat_send(&f_msg, len);
-
-			f_msg.m_nentries = 0;
 		}
-	}
 
-	/*
-	 * Send the rest
-	 */
-	if (f_msg.m_nentries > 0)
-	{
-		len = offsetof(PgStat_MsgFuncpurge, m_functionid[0])
-			+f_msg.m_nentries * sizeof(Oid);
-
-		pgstat_send(&f_msg, len);
+		hash_destroy(htab);
 	}
-
-	hash_destroy(htab);
 }
 
 
-- 
GitLab