]> granicus.if.org Git - postgresql/commitdiff
Fix thinko: cost_mergejoin must pay attention to which side of the
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Mar 2002 20:50:20 +0000 (20:50 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Mar 2002 20:50:20 +0000 (20:50 +0000)
mergeclause is which when extracting selectivity info.

src/backend/optimizer/path/costsize.c

index a94d54342e4374ec5fbff0bb50716f374339d555..e215a6cd3669e6e400aa23eef3049ab170931562 100644 (file)
@@ -42,7 +42,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.81 2002/03/01 06:01:19 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.82 2002/03/01 20:50:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -467,10 +467,11 @@ cost_sort(Path *path, Query *root,
        }
 
        /*
-        * Note: should we bother to assign a nonzero run_cost to reflect the
-        * overhead of extracting tuples from the sort result?  Probably not
-        * worth worrying about.
+        * Also charge a small amount (arbitrarily set equal to operator cost)
+        * per extracted tuple.
         */
+       run_cost += cpu_operator_cost * tuples;
+
        path->startup_cost = startup_cost;
        path->total_cost = startup_cost + run_cost;
 }
@@ -567,11 +568,12 @@ cost_mergejoin(Path *path, Query *root,
        Cost            run_cost = 0;
        Cost            cpu_per_tuple;
        RestrictInfo *firstclause;
+       Var                *leftvar;
        double          outer_rows,
                                inner_rows;
        double          ntuples;
-       Selectivity     leftscan,
-                               rightscan;
+       Selectivity     outerscansel,
+                               innerscansel;
        Path            sort_path;              /* dummy for result of cost_sort */
 
        if (!enable_mergejoin)
@@ -592,11 +594,24 @@ cost_mergejoin(Path *path, Query *root,
                mergejoinscansel(root, (Node *) firstclause->clause,
                                                 &firstclause->left_mergescansel,
                                                 &firstclause->right_mergescansel);
-       leftscan = firstclause->left_mergescansel;
-       rightscan = firstclause->right_mergescansel;
 
-       outer_rows = outer_path->parent->rows * leftscan;
-       inner_rows = inner_path->parent->rows * rightscan;
+       leftvar = get_leftop(firstclause->clause);
+       Assert(IsA(leftvar, Var));
+       if (intMember(leftvar->varno, outer_path->parent->relids))
+       {
+               /* left side of clause is outer */
+               outerscansel = firstclause->left_mergescansel;
+               innerscansel = firstclause->right_mergescansel;
+       }
+       else
+       {
+               /* left side of clause is inner */
+               outerscansel = firstclause->right_mergescansel;
+               innerscansel = firstclause->left_mergescansel;
+       }
+
+       outer_rows = outer_path->parent->rows * outerscansel;
+       inner_rows = inner_path->parent->rows * innerscansel;
 
        /* cost of source data */
 
@@ -616,13 +631,13 @@ cost_mergejoin(Path *path, Query *root,
                                  outer_path->parent->width);
                startup_cost += sort_path.startup_cost;
                run_cost += (sort_path.total_cost - sort_path.startup_cost)
-                       * leftscan;
+                       * outerscansel;
        }
        else
        {
                startup_cost += outer_path->startup_cost;
                run_cost += (outer_path->total_cost - outer_path->startup_cost)
-                       * leftscan;
+                       * outerscansel;
        }
 
        if (innersortkeys)                      /* do we need to sort inner? */
@@ -635,13 +650,13 @@ cost_mergejoin(Path *path, Query *root,
                                  inner_path->parent->width);
                startup_cost += sort_path.startup_cost;
                run_cost += (sort_path.total_cost - sort_path.startup_cost)
-                       * rightscan;
+                       * innerscansel;
        }
        else
        {
                startup_cost += inner_path->startup_cost;
                run_cost += (inner_path->total_cost - inner_path->startup_cost)
-                       * rightscan;
+                       * innerscansel;
        }
 
        /*