]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Make EXPLAIN results for Append, Group, Agg, Unique nodes more plausible.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Feb 2000 06:12:19 +0000 (06:12 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Feb 2000 06:12:19 +0000 (06:12 +0000)
Group and Unique use an arbitrary assumption that there will be about
10% as many groups as input tuples --- perhaps someday we can refine this.

src/backend/optimizer/plan/createplan.c
src/backend/optimizer/prep/prepunion.c

index 70a73821641bebd691293fa9fd00e220b3c2b168..69c0a3f65be8bd0e454c253443a8b8daac54e4e2 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.82 2000/01/27 18:11:30 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.83 2000/02/03 06:12:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -743,9 +743,9 @@ create_hashjoin_node(HashPath *best_path,
  *     * Var nodes representing index keys must have varattno equal to the
  *       index's attribute number, not the attribute number in the original rel.
  *     * indxpath.c may have selected an index that is binary-compatible with
- *       the actual expression operator, but not the same; we must replace the
- *       expression's operator with the binary-compatible equivalent operator
- *       that the index will recognize.
+ *       the actual expression operator, but not exactly the same datatype.
+ *       We must replace the expression's operator with the binary-compatible
+ *       equivalent operator that the index will recognize.
  *     * If the index key is on the right, commute the clause to put it on the
  *       left.  (Someday the executor might not need this, but for now it does.)
  *
@@ -1054,6 +1054,7 @@ copy_path_costsize(Plan *dest, Path *src)
  * Copy cost and size info from a lower plan node to an inserted node.
  * This is not critical, since the decisions have already been made,
  * but it helps produce more reasonable-looking EXPLAIN output.
+ * (Some callers alter the info after copying it.)
  */
 static void
 copy_plan_costsize(Plan *dest, Plan *src)
@@ -1178,12 +1179,7 @@ make_nestloop(List *qptlist,
        NestLoop   *node = makeNode(NestLoop);
        Plan       *plan = &node->join;
 
-       /*
-        * this cost estimate is entirely bogus... hopefully it will be
-        * overwritten by caller.
-        */
-       plan->cost = (lefttree ? lefttree->cost : 0) +
-               (righttree ? righttree->cost : 0);
+       /* cost should be inserted by caller */
        plan->state = (EState *) NULL;
        plan->targetlist = qptlist;
        plan->qual = qpqual;
@@ -1204,12 +1200,7 @@ make_hashjoin(List *tlist,
        HashJoin   *node = makeNode(HashJoin);
        Plan       *plan = &node->join;
 
-       /*
-        * this cost estimate is entirely bogus... hopefully it will be
-        * overwritten by caller.
-        */
-       plan->cost = (lefttree ? lefttree->cost : 0) +
-               (righttree ? righttree->cost : 0);
+       /* cost should be inserted by caller */
        plan->state = (EState *) NULL;
        plan->targetlist = tlist;
        plan->qual = qpqual;
@@ -1248,12 +1239,7 @@ make_mergejoin(List *tlist,
        MergeJoin  *node = makeNode(MergeJoin);
        Plan       *plan = &node->join;
 
-       /*
-        * this cost estimate is entirely bogus... hopefully it will be
-        * overwritten by caller.
-        */
-       plan->cost = (lefttree ? lefttree->cost : 0) +
-               (righttree ? righttree->cost : 0);
+       /* cost should be inserted by caller */
        plan->state = (EState *) NULL;
        plan->targetlist = tlist;
        plan->qual = qpqual;
@@ -1293,6 +1279,7 @@ make_material(List *tlist,
        Plan       *plan = &node->plan;
 
        copy_plan_costsize(plan, lefttree);
+       /* XXX shouldn't we charge some additional cost for materialization? */
        plan->state = (EState *) NULL;
        plan->targetlist = tlist;
        plan->qual = NIL;
@@ -1310,6 +1297,20 @@ make_agg(List *tlist, Plan *lefttree)
        Agg                *node = makeNode(Agg);
 
        copy_plan_costsize(&node->plan, lefttree);
+       /*
+        * The tuple width from the input node is OK, as is the cost (we are
+        * ignoring the cost of computing the aggregate; is there any value
+        * in accounting for it?).  But the tuple count is bogus.  We will
+        * produce a single tuple if the input is not a Group, and a tuple
+        * per group otherwise.  For now, estimate the number of groups as
+        * 10% of the number of tuples --- bogus, but how to do better?
+        * (Note we assume the input Group node is in "tuplePerGroup" mode,
+        * so it didn't reduce its row count already.)
+        */
+       if (IsA(lefttree, Group))
+               node->plan.plan_rows *= 0.1;
+       else
+               node->plan.plan_rows = 1;
        node->plan.state = (EState *) NULL;
        node->plan.qual = NULL;
        node->plan.targetlist = tlist;
@@ -1329,6 +1330,15 @@ make_group(List *tlist,
        Group      *node = makeNode(Group);
 
        copy_plan_costsize(&node->plan, lefttree);
+       /*
+        * If tuplePerGroup (which is named exactly backwards) is true,
+        * we will return all the input tuples, so the input node's row count
+        * is OK.  Otherwise, we'll return only one tuple from each group.
+        * For now, estimate the number of groups as 10% of the number of
+        * tuples --- bogus, but how to do better?
+        */
+       if (! tuplePerGroup)
+               node->plan.plan_rows *= 0.1;
        node->plan.state = (EState *) NULL;
        node->plan.qual = NULL;
        node->plan.targetlist = tlist;
@@ -1357,6 +1367,11 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList)
        List       *slitem;
 
        copy_plan_costsize(plan, lefttree);
+       /*
+        * As for Group, we make the unsupported assumption that there will be
+        * 10% as many tuples out as in.
+        */
+       plan->plan_rows *= 0.1;
        plan->state = (EState *) NULL;
        plan->targetlist = tlist;
        plan->qual = NIL;
index 4323b652e8d8a8fd2844c902ba4d1d0a2021b8a0..95005f166f164187d44e3c547b8ae70d2b664971 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.42 2000/01/27 18:11:32 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.43 2000/02/03 06:12:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -218,11 +218,11 @@ plan_union_queries(Query *parse)
        parse->havingQual = NULL;
        parse->hasAggs = false;
 
-       return (make_append(union_plans,
-                                               union_rts,
-                                               0,
-                                               NULL,
-                                               parse->targetList));
+       return make_append(union_plans,
+                                          union_rts,
+                                          0,
+                                          NULL,
+                                          parse->targetList);
 }
 
 
@@ -272,11 +272,11 @@ plan_inherit_queries(Query *parse, List *tlist, Index rt_index)
        union_plans = plan_inherit_query(union_relids, rt_index, rt_entry,
                                                                         parse, tlist, &inheritrtable);
 
-       return (make_append(union_plans,
-                                               NULL,
-                                               rt_index,
-                                               inheritrtable,
-                                               ((Plan *) lfirst(union_plans))->targetlist));
+       return make_append(union_plans,
+                                          NULL,
+                                          rt_index,
+                                          inheritrtable,
+                                          ((Plan *) lfirst(union_plans))->targetlist);
 }
 
 /*
@@ -551,9 +551,18 @@ make_append(List *appendplans,
        node->unionrtables = unionrtables;
        node->inheritrelid = rt_index;
        node->inheritrtable = inheritrtable;
-       node->plan.cost = 0.0;
+       node->plan.cost = 0;
+       node->plan.plan_rows = 0;
+       node->plan.plan_width = 0;
        foreach(subnode, appendplans)
-               node->plan.cost += ((Plan *) lfirst(subnode))->cost;
+       {
+               Plan   *subplan = (Plan *) lfirst(subnode);
+
+               node->plan.cost += subplan->cost;
+               node->plan.plan_rows += subplan->plan_rows;
+               if (node->plan.plan_width < subplan->plan_width)
+                       node->plan.plan_width = subplan->plan_width;
+       }
        node->plan.state = (EState *) NULL;
        node->plan.targetlist = tlist;
        node->plan.qual = NIL;