diff --git c/src/backend/utils/adt/numutils.c i/src/backend/utils/adt/numutils.c
index 471fbb7ee63..52bbff801d0 100644
--- c/src/backend/utils/adt/numutils.c
+++ i/src/backend/utils/adt/numutils.c
@@ -301,6 +301,53 @@ pg_strtoint32_safe(const char *s, Node *escontext)
 	uint32		tmp = 0;
 	bool		neg = false;
 
+	/*
+	 * Fast path recognizing the most common output.
+	 */
+	if (1)
+	{
+		int32		tmp_s = 0;
+
+		/* leading spaces are uncommon => slow path */
+
+		/* handle - sign, + is uncommon => slow path */
+		if (*ptr == '-')
+		{
+			ptr++;
+			neg = true;
+		}
+
+		/* require at least one digit */
+		if (unlikely(!isdigit((unsigned char) *ptr)))
+			goto slow;
+
+		/* process digits */
+		while (*ptr && isdigit((unsigned char) *ptr))
+		{
+			int8		digit = (*ptr++ - '0');
+
+			if (unlikely(pg_mul_s32_overflow(tmp_s, 10, &tmp_s)) ||
+				unlikely(pg_sub_s32_overflow(tmp_s, digit, &tmp_s)))
+				goto out_of_range;
+		}
+
+		/* trailing spaces are uncommon => slow path */
+		if (unlikely(*ptr != '\0'))
+			goto slow;
+
+		if (!neg)
+		{
+			/* could fail if input is most negative number */
+			if (unlikely(tmp == PG_INT32_MIN))
+				goto out_of_range;
+			tmp = -tmp;
+		}
+
+		return tmp;
+	}
+
+slow:
+
 	/* skip leading spaces */
 	while (likely(*ptr) && isspace((unsigned char) *ptr))
 		ptr++;
