On 28.10.2010 13:54, Boszormenyi Zoltan wrote:
A little better version, no need for the heavy hash_any, hash_uint32 on the lower 32 bits on pk_eclass is enough. The profiling runtime is now 0.42 seconds vs the previous 0.41 seconds for the tree version.
Actually, I wonder if we could just have a separate canon_pathkeys list for each EquivalenceClass, instead of one big list in PlannerInfo. I'm not too familiar with equivalence classes and all that, but the attached patch at least passes the regressions. I haven't done any performance testing, but I would expect this to be even faster than the hashtable or tree implementations, and a lot simpler.
-- Heikki Linnakangas EnterpriseDB http://www.enterprisedb.com
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index ee2aeb0..7a12c47 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -1595,7 +1595,6 @@ _outPlannerInfo(StringInfo str, PlannerInfo *node) WRITE_NODE_FIELD(init_plans); WRITE_NODE_FIELD(cte_plan_ids); WRITE_NODE_FIELD(eq_classes); - WRITE_NODE_FIELD(canon_pathkeys); WRITE_NODE_FIELD(left_join_clauses); WRITE_NODE_FIELD(right_join_clauses); WRITE_NODE_FIELD(full_join_clauses); @@ -1692,6 +1691,7 @@ _outEquivalenceClass(StringInfo str, EquivalenceClass *node) WRITE_BOOL_FIELD(ec_below_outer_join); WRITE_BOOL_FIELD(ec_broken); WRITE_UINT_FIELD(ec_sortref); + WRITE_NODE_FIELD(ec_canon_pathkeys); } static void diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index 643d57a..d5e5c42 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -93,9 +93,10 @@ make_canonical_pathkey(PlannerInfo *root, while (eclass->ec_merged) eclass = eclass->ec_merged; - foreach(lc, root->canon_pathkeys) + foreach(lc, eclass->ec_canon_pathkeys) { pk = (PathKey *) lfirst(lc); + Assert(eclass == pk->pk_eclass); if (eclass == pk->pk_eclass && opfamily == pk->pk_opfamily && strategy == pk->pk_strategy && @@ -110,7 +111,7 @@ make_canonical_pathkey(PlannerInfo *root, oldcontext = MemoryContextSwitchTo(root->planner_cxt); pk = makePathKey(eclass, opfamily, strategy, nulls_first); - root->canon_pathkeys = lappend(root->canon_pathkeys, pk); + eclass->ec_canon_pathkeys = lappend(eclass->ec_canon_pathkeys, pk); MemoryContextSwitchTo(oldcontext); diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index fd4c6f5..5f8f817 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -117,7 +117,10 @@ query_planner(PlannerInfo *root, List *tlist, * We still are required to canonicalize any pathkeys, in case it's * something like "SELECT 2+2 ORDER BY 1". */ +/* XXX: Same as below */ +#if 0 root->canon_pathkeys = NIL; +#endif root->query_pathkeys = canonicalize_pathkeys(root, root->query_pathkeys); root->group_pathkeys = canonicalize_pathkeys(root, @@ -145,7 +148,13 @@ query_planner(PlannerInfo *root, List *tlist, root->join_rel_hash = NULL; root->join_rel_level = NULL; root->join_cur_level = 0; - root->canon_pathkeys = NIL; +/* XXX + * Do we need to reset something here? This is just initializing otherwise + * uninitialized fields, right? + */ +#if 0 + root->canon_pathkeys = NIL; +#endif root->left_join_clauses = NIL; root->right_join_clauses = NIL; root->full_join_clauses = NIL; diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 6e3d0f3..c959708 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -160,8 +160,6 @@ typedef struct PlannerInfo List *eq_classes; /* list of active EquivalenceClasses */ - List *canon_pathkeys; /* list of "canonical" PathKeys */ - List *left_join_clauses; /* list of RestrictInfos for * mergejoinable outer join clauses * w/nonnullable var on left */ @@ -527,6 +525,7 @@ typedef struct EquivalenceClass bool ec_below_outer_join; /* equivalence applies below an OJ */ bool ec_broken; /* failed to generate needed clauses? */ Index ec_sortref; /* originating sortclause label, or 0 */ + List *ec_canon_pathkeys; struct EquivalenceClass *ec_merged; /* set if merged into another EC */ } EquivalenceClass;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers