diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2010-03-28 22:59:34 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2010-03-28 22:59:34 +0000 |
commit | b78f6264eba33e2966447572b8261e353df01e59 (patch) | |
tree | 1b5cfa84c32c6683851d335cfa9cd7dab54ecee5 /src/backend/optimizer/plan/planmain.c | |
parent | a760893dbda9934e287789d54bbd3c4ca3914ce0 (diff) |
Rework join-removal logic as per recent discussion. In particular this
fixes things so that it works for cases where nested removals are possible.
The overhead of the optimization should be significantly less, as well.
Diffstat (limited to 'src/backend/optimizer/plan/planmain.c')
-rw-r--r-- | src/backend/optimizer/plan/planmain.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index a53b4e1c515..f93205bbaa7 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.117 2010/01/02 16:57:47 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.118 2010/03/28 22:59:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -180,31 +180,6 @@ query_planner(PlannerInfo *root, List *tlist, add_base_rels_to_query(root, (Node *) parse->jointree); /* - * We should now have size estimates for every actual table involved in - * the query, so we can compute total_table_pages. Note that appendrels - * are not double-counted here, even though we don't bother to distinguish - * RelOptInfos for appendrel parents, because the parents will still have - * size zero. - * - * XXX if a table is self-joined, we will count it once per appearance, - * which perhaps is the wrong thing ... but that's not completely clear, - * and detecting self-joins here is difficult, so ignore it for now. - */ - total_pages = 0; - for (rti = 1; rti < root->simple_rel_array_size; rti++) - { - RelOptInfo *brel = root->simple_rel_array[rti]; - - if (brel == NULL) - continue; - - Assert(brel->relid == rti); /* sanity check on array */ - - total_pages += (double) brel->pages; - } - root->total_table_pages = total_pages; - - /* * Examine the targetlist and qualifications, adding entries to baserel * targetlists for all referenced Vars. Restrict and join clauses are * added to appropriate lists belonging to the mentioned relations. We @@ -249,6 +224,49 @@ query_planner(PlannerInfo *root, List *tlist, fix_placeholder_eval_levels(root); /* + * Remove any useless outer joins. Ideally this would be done during + * jointree preprocessing, but the necessary information isn't available + * until we've built baserel data structures and classified qual clauses. + */ + joinlist = remove_useless_joins(root, joinlist); + + /* + * Now distribute "placeholders" to base rels as needed. This has to be + * done after join removal because removal could change whether a + * placeholder is evaluatable at a base rel. + */ + add_placeholders_to_base_rels(root); + + /* + * We should now have size estimates for every actual table involved in + * the query, and we also know which if any have been deleted from the + * query by join removal; so we can compute total_table_pages. + * + * Note that appendrels are not double-counted here, even though we don't + * bother to distinguish RelOptInfos for appendrel parents, because the + * parents will still have size zero. + * + * XXX if a table is self-joined, we will count it once per appearance, + * which perhaps is the wrong thing ... but that's not completely clear, + * and detecting self-joins here is difficult, so ignore it for now. + */ + total_pages = 0; + for (rti = 1; rti < root->simple_rel_array_size; rti++) + { + RelOptInfo *brel = root->simple_rel_array[rti]; + + if (brel == NULL) + continue; + + Assert(brel->relid == rti); /* sanity check on array */ + + if (brel->reloptkind == RELOPT_BASEREL || + brel->reloptkind == RELOPT_OTHER_MEMBER_REL) + total_pages += (double) brel->pages; + } + root->total_table_pages = total_pages; + + /* * Ready to do the primary planning. */ final_rel = make_one_rel(root, joinlist); |