diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 7f820e7351..c6aa17ba67 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -1875,16 +1875,8 @@ cost_incremental_sort(Path *path,
 				   limit_tuples);
 
 	/* If we have a LIMIT, adjust the number of groups we'll have to return. */
-	if (limit_tuples > 0 && limit_tuples < input_tuples)
-	{
-		output_tuples = limit_tuples;
-		output_groups = floor(output_tuples / group_tuples) + 1;
-	}
-	else
-	{
-		output_tuples = input_tuples;
-		output_groups = input_groups;
-	}
+	output_tuples = input_tuples;
+	output_groups = input_groups;
 
 	/*
 	 * Startup cost of incremental sort is the startup cost of its first group
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 16996b1bc2..cb709b8764 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -5033,15 +5033,20 @@ create_ordered_paths(PlannerInfo *root,
 		input_rel->partial_pathlist != NIL)
 	{
 		Path	   *cheapest_partial_path;
+		bool		is_sorted;
+		int			presorted_keys;
 
 		cheapest_partial_path = linitial(input_rel->partial_pathlist);
 
+		is_sorted = pathkeys_common_contained_in(root->sort_pathkeys,
+												 cheapest_partial_path->pathkeys,
+												 &presorted_keys);
+
 		/*
 		 * If cheapest partial path doesn't need a sort, this is redundant
 		 * with what's already been tried.
 		 */
-		if (!pathkeys_contained_in(root->sort_pathkeys,
-								   cheapest_partial_path->pathkeys))
+		if (!is_sorted)
 		{
 			Path	   *path;
 			double		total_groups;
@@ -5067,6 +5072,34 @@ create_ordered_paths(PlannerInfo *root,
 												path, target);
 
 			add_path(ordered_rel, path);
+
+			/*
+			 * If already partially sorted then we should also consider
+			 * incremental sort.
+			 */
+			if (presorted_keys > 0)
+			{
+				path = (Path *) create_incremental_sort_path(root,
+															 ordered_rel,
+															 cheapest_partial_path,
+															 root->sort_pathkeys,
+															 presorted_keys,
+															 limit_tuples);
+
+				path = (Path *)
+					create_gather_merge_path(root, ordered_rel,
+											 path,
+											 path->pathtarget,
+											 root->sort_pathkeys, NULL,
+											 &total_groups);
+
+				/* Add projection step if needed */
+				if (path->pathtarget != target)
+					path = apply_projection_to_path(root, ordered_rel,
+													path, target);
+
+				add_path(ordered_rel, path);
+			}
 		}
 	}
 
@@ -6939,14 +6972,20 @@ static void
 gather_grouping_paths(PlannerInfo *root, RelOptInfo *rel)
 {
 	Path	   *cheapest_partial_path;
+	bool		is_sorted;
+	int			presorted_keys;
 
 	/* Try Gather for unordered paths and Gather Merge for ordered ones. */
 	generate_gather_paths(root, rel, true);
 
 	/* Try cheapest partial path + explicit Sort + Gather Merge. */
 	cheapest_partial_path = linitial(rel->partial_pathlist);
-	if (!pathkeys_contained_in(root->group_pathkeys,
-							   cheapest_partial_path->pathkeys))
+
+	is_sorted = pathkeys_common_contained_in(root->group_pathkeys,
+											 cheapest_partial_path->pathkeys,
+											 &presorted_keys);
+
+	if (!is_sorted)
 	{
 		Path	   *path;
 		double		total_groups;
@@ -6966,6 +7005,31 @@ gather_grouping_paths(PlannerInfo *root, RelOptInfo *rel)
 									 &total_groups);
 
 		add_path(rel, path);
+
+		/*
+		 * If already partially sorted then we should also consider
+		 * incremental sort.
+		 */
+		if (presorted_keys > 0)
+		{
+			path = (Path *) create_incremental_sort_path(root,
+														 rel,
+														 cheapest_partial_path,
+														 root->group_pathkeys,
+														 presorted_keys,
+														 -1.0);
+
+			path = (Path *)
+				create_gather_merge_path(root,
+										 rel,
+										 path,
+										 rel->reltarget,
+										 root->group_pathkeys,
+										 NULL,
+										 &total_groups);
+
+			add_path(rel, path);
+		}
 	}
 }
 
