summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2001-04-25 22:04:37 +0000
committerTom Lane2001-04-25 22:04:37 +0000
commita43f20cb0a38523dd4dcf6265884e30ba2b1ec22 (patch)
tree4200dd3c7b7f523934aff66e62701a8e556e0726
parentcbeda8401a948515780ad49001c577e07036699c (diff)
Tweak nestloop costing to weight restart cost of inner path more heavily.
Without this, it was making some pretty silly decisions about whether an expensive sub-SELECT should be the inner or outer side of a join...
-rw-r--r--src/backend/optimizer/path/costsize.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index d5b343a90cf..c52af72a16b 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -41,7 +41,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.69 2001/03/22 03:59:34 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.70 2001/04/25 22:04:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -443,14 +443,22 @@ cost_nestloop(Path *path,
/* cost of source data */
/*
- * NOTE: we assume that the inner path's startup_cost is paid once,
- * not over again on each restart. This is certainly correct if the
- * inner path is materialized. Are there any cases where it is wrong?
+ * NOTE: clearly, we must pay both outer and inner paths' startup_cost
+ * before we can start returning tuples, so the join's startup cost
+ * is their sum. What's not so clear is whether the inner path's
+ * startup_cost must be paid again on each rescan of the inner path.
+ * This is not true if the inner path is materialized, but probably
+ * is true otherwise. Since we don't yet have clean handling of the
+ * decision whether to materialize a path, we can't tell here which
+ * will happen. As a compromise, charge 50% of the inner startup cost
+ * for each restart.
*/
startup_cost += outer_path->startup_cost + inner_path->startup_cost;
run_cost += outer_path->total_cost - outer_path->startup_cost;
run_cost += outer_path->parent->rows *
(inner_path->total_cost - inner_path->startup_cost);
+ if (outer_path->parent->rows > 1)
+ run_cost += (outer_path->parent->rows - 1) * inner_path->startup_cost;
/*
* Number of tuples processed (not number emitted!). If inner path is