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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers