summaryrefslogtreecommitdiff
path: root/src/backend/nodes/outfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-02-15 20:49:31 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-02-15 20:49:31 +0000
commitb1577a7c78d2d8880b3c0f94689fb75bd074c897 (patch)
treec8d8f0500eb2eaa085d921a46a7d0987ba594a4a /src/backend/nodes/outfuncs.c
parent553b5da6a1147881dc1df101ecf9bab75f767ccf (diff)
New cost model for planning, incorporating a penalty for random page
accesses versus sequential accesses, a (very crude) estimate of the effects of caching on random page accesses, and cost to evaluate WHERE- clause expressions. Export critical parameters for this model as SET variables. Also, create SET variables for the planner's enable flags (enable_seqscan, enable_indexscan, etc) so that these can be controlled more conveniently than via PGOPTIONS. Planner now estimates both startup cost (cost before retrieving first tuple) and total cost of each path, so it can optimize queries with LIMIT on a reasonable basis by interpolating between these costs. Same facility is a win for EXISTS(...) subqueries and some other cases. Redesign pathkey representation to achieve a major speedup in planning (I saw as much as 5X on a 10-way join); also minor changes in planner to reduce memory consumption by recycling discarded Path nodes and not constructing unnecessary lists. Minor cleanups to display more-plausible costs in some cases in EXPLAIN output. Initdb forced by change in interface to index cost estimation functions.
Diffstat (limited to 'src/backend/nodes/outfuncs.c')
-rw-r--r--src/backend/nodes/outfuncs.c65
1 files changed, 36 insertions, 29 deletions
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index e4c35cc277f..c40ca9ff9cb 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.107 2000/02/15 03:37:09 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.108 2000/02/15 20:49:09 tgl Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -321,8 +321,9 @@ static void
_outPlanInfo(StringInfo str, Plan *node)
{
appendStringInfo(str,
- ":cost %g :rows %.0f :width %d :state %s :qptargetlist ",
- node->cost,
+ ":startup_cost %.2f :total_cost %.2f :rows %.0f :width %d :state %s :qptargetlist ",
+ node->startup_cost,
+ node->total_cost,
node->plan_rows,
node->plan_width,
node->state ? "not-NULL" : "<>");
@@ -908,15 +909,13 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node)
appendStringInfo(str, " :pathlist ");
_outNode(str, node->pathlist);
- /*
- * Not sure if these are nodes or not. They're declared as struct
- * Path *. Since i don't know, i'll just print the addresses for now.
- * This can be changed later, if necessary.
- */
+ appendStringInfo(str, " :cheapest_startup_path ");
+ _outNode(str, node->cheapest_startup_path);
+ appendStringInfo(str, " :cheapest_total_path ");
+ _outNode(str, node->cheapest_total_path);
appendStringInfo(str,
- " :cheapestpath @ 0x%x :pruneable %s :baserestrictinfo ",
- (int) node->cheapestpath,
+ " :pruneable %s :baserestrictinfo ",
node->pruneable ? "true" : "false");
_outNode(str, node->baserestrictinfo);
@@ -977,9 +976,11 @@ _outRowMark(StringInfo str, RowMark *node)
static void
_outPath(StringInfo str, Path *node)
{
- appendStringInfo(str, " PATH :pathtype %d :cost %.2f :pathkeys ",
+ appendStringInfo(str,
+ " PATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->pathtype,
- node->path_cost);
+ node->startup_cost,
+ node->total_cost);
_outNode(str, node->pathkeys);
}
@@ -990,9 +991,10 @@ static void
_outIndexPath(StringInfo str, IndexPath *node)
{
appendStringInfo(str,
- " INDEXPATH :pathtype %d :cost %.2f :pathkeys ",
+ " INDEXPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->path.pathtype,
- node->path.path_cost);
+ node->path.startup_cost,
+ node->path.total_cost);
_outNode(str, node->path.pathkeys);
appendStringInfo(str, " :indexid ");
@@ -1001,7 +1003,8 @@ _outIndexPath(StringInfo str, IndexPath *node)
appendStringInfo(str, " :indexqual ");
_outNode(str, node->indexqual);
- appendStringInfo(str, " :joinrelids ");
+ appendStringInfo(str, " :indexscandir %d :joinrelids ",
+ (int) node->indexscandir);
_outIntList(str, node->joinrelids);
}
@@ -1012,9 +1015,10 @@ static void
_outTidPath(StringInfo str, TidPath *node)
{
appendStringInfo(str,
- " TIDPATH :pathtype %d :cost %.2f :pathkeys ",
+ " TIDPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->path.pathtype,
- node->path.path_cost);
+ node->path.startup_cost,
+ node->path.total_cost);
_outNode(str, node->path.pathkeys);
appendStringInfo(str, " :tideval ");
@@ -1031,9 +1035,10 @@ static void
_outNestPath(StringInfo str, NestPath *node)
{
appendStringInfo(str,
- " NESTPATH :pathtype %d :cost %.2f :pathkeys ",
+ " NESTPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->path.pathtype,
- node->path.path_cost);
+ node->path.startup_cost,
+ node->path.total_cost);
_outNode(str, node->path.pathkeys);
appendStringInfo(str, " :outerjoinpath ");
_outNode(str, node->outerjoinpath);
@@ -1050,9 +1055,10 @@ static void
_outMergePath(StringInfo str, MergePath *node)
{
appendStringInfo(str,
- " MERGEPATH :pathtype %d :cost %.2f :pathkeys ",
+ " MERGEPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->jpath.path.pathtype,
- node->jpath.path.path_cost);
+ node->jpath.path.startup_cost,
+ node->jpath.path.total_cost);
_outNode(str, node->jpath.path.pathkeys);
appendStringInfo(str, " :outerjoinpath ");
_outNode(str, node->jpath.outerjoinpath);
@@ -1078,9 +1084,10 @@ static void
_outHashPath(StringInfo str, HashPath *node)
{
appendStringInfo(str,
- " HASHPATH :pathtype %d :cost %.2f :pathkeys ",
+ " HASHPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->jpath.path.pathtype,
- node->jpath.path.path_cost);
+ node->jpath.path.startup_cost,
+ node->jpath.path.total_cost);
_outNode(str, node->jpath.path.pathkeys);
appendStringInfo(str, " :outerjoinpath ");
_outNode(str, node->jpath.outerjoinpath);
@@ -1364,7 +1371,7 @@ _outNode(StringInfo str, void *obj)
return;
}
- if (nodeTag(obj) == T_List)
+ if (IsA(obj, List))
{
List *l;
@@ -1377,6 +1384,11 @@ _outNode(StringInfo str, void *obj)
}
appendStringInfoChar(str, ')');
}
+ else if (IsA_Value(obj))
+ {
+ /* nodeRead does not want to see { } around these! */
+ _outValue(str, obj);
+ }
else
{
appendStringInfoChar(str, '{');
@@ -1550,11 +1562,6 @@ _outNode(StringInfo str, void *obj)
case T_Stream:
_outStream(str, obj);
break;
- case T_Integer:
- case T_String:
- case T_Float:
- _outValue(str, obj);
- break;
case T_A_Expr:
_outAExpr(str, obj);
break;