Skip to content

Commit 94cad7a

Browse files
committed
Optimize generate_orderedappend_paths
In generate_orderedappend_paths(), when match_partition_order_desc was true, we would lcons() items to various lists in a loop over each live partition. When the number of live partitions was large, the lcons() could show up in profiles due to it having to perform memmove() to make way for the new list item. Here we adjust things so that we just perform the loop over the live partitions backwards when match_partition_order_desc is true. This allows us to simplify the logic in the loop. Now, as far as the guts of the loop knows, there's no difference between match_partition_order and match_partition_order_desc. We can just set match_partition_order to true so that we build the correct list of paths for the asc and desc case. Per idea from Andres Freund. Discussion: https://postgr.es/m/20230217002351.nyt4y5tdzg6hugdt@awork3.anarazel.de
1 parent 6773197 commit 94cad7a

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

src/backend/optimizer/path/allpaths.c

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,9 +1700,11 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
17001700
List *total_subpaths = NIL;
17011701
List *fractional_subpaths = NIL;
17021702
bool startup_neq_total = false;
1703-
ListCell *lcr;
17041703
bool match_partition_order;
17051704
bool match_partition_order_desc;
1705+
int end_index;
1706+
int first_index;
1707+
int direction;
17061708

17071709
/*
17081710
* Determine if this sort ordering matches any partition pathkeys we
@@ -1723,10 +1725,38 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
17231725
(!partition_pathkeys_desc_partial &&
17241726
pathkeys_contained_in(partition_pathkeys_desc, pathkeys)));
17251727

1728+
/*
1729+
* When the required pathkeys match the reverse of the partition
1730+
* order, we must build the list of paths in reverse starting with the
1731+
* last matching partition first. We can get away without making any
1732+
* special cases for this in the loop below by just looping backward
1733+
* over the child relations in this case.
1734+
*/
1735+
if (match_partition_order_desc)
1736+
{
1737+
/* loop backward */
1738+
first_index = list_length(live_childrels) - 1;
1739+
end_index = -1;
1740+
direction = -1;
1741+
1742+
/*
1743+
* Set this to true to save us having to check for
1744+
* match_partition_order_desc in the loop below.
1745+
*/
1746+
match_partition_order = true;
1747+
}
1748+
else
1749+
{
1750+
/* for all other case, loop forward */
1751+
first_index = 0;
1752+
end_index = list_length(live_childrels);
1753+
direction = 1;
1754+
}
1755+
17261756
/* Select the child paths for this ordering... */
1727-
foreach(lcr, live_childrels)
1757+
for (int i = first_index; i != end_index; i += direction)
17281758
{
1729-
RelOptInfo *childrel = (RelOptInfo *) lfirst(lcr);
1759+
RelOptInfo *childrel = list_nth_node(RelOptInfo, live_childrels, i);
17301760
Path *cheapest_startup,
17311761
*cheapest_total,
17321762
*cheapest_fractional = NULL;
@@ -1822,25 +1852,6 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
18221852
fractional_subpaths = lappend(fractional_subpaths, cheapest_fractional);
18231853
}
18241854
}
1825-
else if (match_partition_order_desc)
1826-
{
1827-
/*
1828-
* As above, but we need to reverse the order of the children,
1829-
* because nodeAppend.c doesn't know anything about reverse
1830-
* ordering and will scan the children in the order presented.
1831-
*/
1832-
cheapest_startup = get_singleton_append_subpath(cheapest_startup);
1833-
cheapest_total = get_singleton_append_subpath(cheapest_total);
1834-
1835-
startup_subpaths = lcons(cheapest_startup, startup_subpaths);
1836-
total_subpaths = lcons(cheapest_total, total_subpaths);
1837-
1838-
if (cheapest_fractional)
1839-
{
1840-
cheapest_fractional = get_singleton_append_subpath(cheapest_fractional);
1841-
fractional_subpaths = lcons(cheapest_fractional, fractional_subpaths);
1842-
}
1843-
}
18441855
else
18451856
{
18461857
/*
@@ -1859,7 +1870,7 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
18591870
}
18601871

18611872
/* ... and build the Append or MergeAppend paths */
1862-
if (match_partition_order || match_partition_order_desc)
1873+
if (match_partition_order)
18631874
{
18641875
/* We only need Append */
18651876
add_path(rel, (Path *) create_append_path(root,

0 commit comments

Comments
 (0)