1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

Nab some low-hanging fruit: replace the planner's base_rel_list and

other_rel_list with a single array indexed by rangetable index.
This reduces find_base_rel from O(N) to O(1) without any real penalty.
While find_base_rel isn't one of the major bottlenecks in any profile
I've seen so far, it was starting to creep up on the radar screen
for complex queries --- so might as well fix it.
This commit is contained in:
Tom Lane
2005-06-06 04:13:36 +00:00
parent 9ab4d98168
commit 9a586fe0c5
5 changed files with 143 additions and 110 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.131 2005/06/05 22:32:55 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.132 2005/06/06 04:13:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -88,9 +88,33 @@ make_one_rel(PlannerInfo *root)
rel = make_fromexpr_rel(root, root->parse->jointree);
/*
* The result should join all the query's base rels.
* The result should join all and only the query's base rels.
*/
Assert(bms_num_members(rel->relids) == list_length(root->base_rel_list));
#ifdef USE_ASSERT_CHECKING
{
int num_base_rels = 0;
Index rti;
for (rti = 1; rti < root->base_rel_array_size; rti++)
{
RelOptInfo *brel = root->base_rel_array[rti];
if (brel == NULL)
continue;
Assert(brel->relid == rti); /* sanity check on array */
/* ignore RTEs that are "other rels" */
if (brel->reloptkind != RELOPT_BASEREL)
continue;
Assert(bms_is_member(rti, rel->relids));
num_base_rels++;
}
Assert(bms_num_members(rel->relids) == num_base_rels);
}
#endif
return rel;
}
@ -104,16 +128,29 @@ make_one_rel(PlannerInfo *root)
static void
set_base_rel_pathlists(PlannerInfo *root)
{
ListCell *l;
Index rti;
foreach(l, root->base_rel_list)
/*
* Note: because we call expand_inherited_rtentry inside the loop,
* it's quite possible for the base_rel_array to be enlarged while
* the loop runs. Hence don't try to optimize the loop.
*/
for (rti = 1; rti < root->base_rel_array_size; rti++)
{
RelOptInfo *rel = (RelOptInfo *) lfirst(l);
Index rti = rel->relid;
RelOptInfo *rel = root->base_rel_array[rti];
RangeTblEntry *rte;
List *inheritlist;
Assert(rti > 0); /* better be base rel */
/* there may be empty slots corresponding to non-baserel RTEs */
if (rel == NULL)
continue;
Assert(rel->relid == rti); /* sanity check on array */
/* ignore RTEs that are "other rels" */
if (rel->reloptkind != RELOPT_BASEREL)
continue;
rte = rt_fetch(rti, root->parse->rtable);
if (rel->rtekind == RTE_SUBQUERY)
@ -246,10 +283,9 @@ set_inherited_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
childOID = childrte->relid;
/*
* Make a RelOptInfo for the child so we can do planning. Do NOT
* attach the RelOptInfo to the query's base_rel_list, however,
* since the child is not part of the main join tree. Instead,
* the child RelOptInfo is added to other_rel_list.
* Make a RelOptInfo for the child so we can do planning.
* Mark it as an "other rel" since it will not be part of the
* main join tree.
*/
childrel = build_other_rel(root, childRTindex);