diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 07f09e1..4b3348a 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -966,10 +966,19 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
 		BufferUsage bufusage_start,
 					bufusage;
 		uint32		queryId;
+		const char *normalQueryString;
 
 		bufusage_start = pgBufferUsage;
 		INSTR_TIME_SET_CURRENT(start);
 
+		/*
+		 * normalize queryString for DEALLOCATE, as drivers such as DBD::Pg
+		 * generate counter-based names for prepared statements which can
+		 * result in many useless entries.
+		 */
+		normalQueryString = strncasecmp(queryString, "DEALLOCATE", 10)==0 ?
+			"DEALLOCATE ?;": queryString;
+
 		nested_level++;
 		PG_TRY();
 		{
@@ -1025,9 +1034,9 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
 		INSTR_TIME_SUBTRACT(bufusage.blk_write_time, bufusage_start.blk_write_time);
 
 		/* For utility statements, we just hash the query string directly */
-		queryId = pgss_hash_string(queryString);
+		queryId = pgss_hash_string(normalQueryString);
 
-		pgss_store(queryString,
+		pgss_store(normalQueryString,
 				   queryId,
 				   INSTR_TIME_GET_MILLISEC(duration),
 				   rows,
