Skip to content

Commit 64919aa

Browse files
committed
Reduce the cost of planning deeply-nested views.
Joel Jacobson reported that deep nesting of trivial (flattenable) views results in O(N^3) growth of planning time for N-deep nesting. It turns out that a large chunk of this cost comes from copying around the "subquery" sub-tree of each view's RTE_SUBQUERY RTE. But once we have successfully flattened the subquery, we don't need that anymore, because the planner isn't going to do anything else interesting with that RTE. We already zap the subquery pointer during setrefs.c (cf. add_rte_to_flat_rtable), but it's useless baggage earlier than that too. Clearing the pointer as soon as pull_up_simple_subquery is done with the RTE reduces the cost from O(N^3) to O(N^2); which is still not great, but it's quite a lot better. Further improvements will require rethinking of the RTE data structure, which is being considered in another thread. Patch by me; thanks to Dean Rasheed for review. Discussion: https://postgr.es/m/797aff54-b49b-4914-9ff9-aa42564a4d7d@www.fastmail.com
1 parent c7b7311 commit 64919aa

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

src/backend/optimizer/prep/prepjointree.c

+11-4
Original file line numberDiff line numberDiff line change
@@ -893,10 +893,9 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
893893
ListCell *lc;
894894

895895
/*
896-
* Need a modifiable copy of the subquery to hack on. Even if we didn't
897-
* sometimes choose not to pull up below, we must do this to avoid
898-
* problems if the same subquery is referenced from multiple jointree
899-
* items (which can't happen normally, but might after rule rewriting).
896+
* Make a modifiable copy of the subquery to hack on, so that the RTE will
897+
* be left unchanged in case we decide below that we can't pull it up
898+
* after all.
900899
*/
901900
subquery = copyObject(rte->subquery);
902901

@@ -1174,6 +1173,14 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
11741173
Assert(root->placeholder_list == NIL);
11751174
Assert(subroot->placeholder_list == NIL);
11761175

1176+
/*
1177+
* We no longer need the RTE's copy of the subquery's query tree. Getting
1178+
* rid of it saves nothing in particular so far as this level of query is
1179+
* concerned; but if this query level is in turn pulled up into a parent,
1180+
* we'd waste cycles copying the now-unused query tree.
1181+
*/
1182+
rte->subquery = NULL;
1183+
11771184
/*
11781185
* Miscellaneous housekeeping.
11791186
*

0 commit comments

Comments
 (0)