From 605d84941dec8179a9680e9757dc9985272c57ce Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 1 May 1999 19:47:42 +0000 Subject: [PATCH] Clean up cost_sort some more: most callers were double-counting the cost of reading the source data. --- src/backend/optimizer/path/costsize.c | 31 +++++++++++-------------- src/backend/optimizer/path/joinpath.c | 7 +++--- src/backend/optimizer/plan/createplan.c | 4 ++-- src/include/optimizer/cost.h | 4 ++-- 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 6bf34c6a25..22eb4d3e53 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.35 1999/04/30 04:01:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.36 1999/05/01 19:47:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -167,28 +167,23 @@ cost_index(Oid indexid, /* * cost_sort * Determines and returns the cost of sorting a relation by considering - * 1. the cost of doing an external sort: XXX this is probably too low + * the cost of doing an external sort: XXX this is probably too low * disk = (p lg p) * cpu = *CPU-PAGE-WEIGHT* * (t lg t) - * 2. the cost of reading the sort result into memory (another seqscan) - * unless 'noread' is set * * 'pathkeys' is a list of sort keys * 'tuples' is the number of tuples in the relation * 'width' is the average tuple width in bytes - * 'noread' is a flag indicating that the cost of reading the sort - * source data should not be included (i.e., the caller - * will account for it separately). * * NOTE: some callers currently pass NULL for pathkeys because they - * can't conveniently supply sort keys. Since this routine doesn't + * can't conveniently supply the sort keys. Since this routine doesn't * currently do anything with pathkeys anyway, that doesn't matter... + * but if it ever does, it should react gracefully to lack of key data. * * Returns a flonum. - * */ Cost -cost_sort(List *pathkeys, int tuples, int width, bool noread) +cost_sort(List *pathkeys, int tuples, int width) { Cost temp = 0; int npages = page_size(tuples, width); @@ -200,6 +195,8 @@ cost_sort(List *pathkeys, int tuples, int width, bool noread) /* We want to be sure the cost of a sort is never estimated as zero, * even if passed-in tuple count is zero. Besides, mustn't do log(0)... */ + if (tuples <= 0) + tuples = 1; if (npages <= 0) npages = 1; @@ -210,13 +207,10 @@ cost_sort(List *pathkeys, int tuples, int width, bool noread) temp += npages * log_npages; /* - * could be base_log(pages, NBuffers), but we are only doing 2-way + * could be base_log(tuples, NBuffers), but we are only doing 2-way * merges */ - temp += _cpu_page_wight_ * tuples * log_npages; - - if (!noread) - temp += cost_seqscan(_NONAME_RELATION_ID_, npages, tuples); + temp += _cpu_page_wight_ * tuples * base_log((double) tuples, 2.0); Assert(temp > 0); @@ -282,7 +276,8 @@ cost_nestloop(Cost outercost, * 'outercost' and 'innercost' are the (disk+cpu) costs of scanning the * outer and inner relations * 'outersortkeys' and 'innersortkeys' are lists of the keys to be used - * to sort the outer and inner relations + * to sort the outer and inner relations (or NIL if no explicit + * sort is needed because the source path is already ordered) * 'outertuples' and 'innertuples' are the number of tuples in the outer * and inner relations * 'outerwidth' and 'innerwidth' are the (typical) widths (in bytes) @@ -309,9 +304,9 @@ cost_mergejoin(Cost outercost, temp += outercost; temp += innercost; if (outersortkeys) /* do we need to sort? */ - temp += cost_sort(outersortkeys, outersize, outerwidth, true); + temp += cost_sort(outersortkeys, outersize, outerwidth); if (innersortkeys) /* do we need to sort? */ - temp += cost_sort(innersortkeys, innersize, innerwidth, true); + temp += cost_sort(innersortkeys, innersize, innerwidth); temp += _cpu_page_wight_ * (outersize + innersize); Assert(temp >= 0); diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 5edfed65b0..8b2f5139ec 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.33 1999/04/03 00:18:28 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.34 1999/05/01 19:47:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -348,7 +348,7 @@ match_unsorted_outer(RelOptInfo *joinrel, (mergeinnerpath->path_cost < (cheapest_inner->path_cost + cost_sort(matchedJoinKeys, innerrel->size, - innerrel->width, false)))); + innerrel->width)))); if (!path_is_cheaper_than_sort) { varkeys = make_pathkeys_from_joinkeys(matchedJoinKeys, @@ -464,8 +464,7 @@ match_unsorted_inner(RelOptInfo *joinrel, if (clauses && matchedJoinKeys) { temp1 = outerrel->cheapestpath->path_cost + - cost_sort(matchedJoinKeys, outerrel->size, outerrel->width, - false); + cost_sort(matchedJoinKeys, outerrel->size, outerrel->width); temp2 = (bool) (FLOAT_IS_ZERO(innerpath->outerjoincost) || (innerpath->outerjoincost > temp1)); diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 095f0ec275..03708897b7 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.51 1999/04/30 04:04:27 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.52 1999/05/01 19:47:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1106,7 +1106,7 @@ make_sort(List *tlist, Oid nonameid, Plan *lefttree, int keycount) Plan *plan = &node->plan; copy_costsize(plan, lefttree); - plan->cost += cost_sort(NULL, plan->plan_size, plan->plan_width, true); + plan->cost += cost_sort(NULL, plan->plan_size, plan->plan_width); plan->state = (EState *) NULL; plan->targetlist = tlist; plan->qual = NIL; diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h index fdaf17d91f..2b752711a6 100644 --- a/src/include/optimizer/cost.h +++ b/src/include/optimizer/cost.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: cost.h,v 1.17 1999/02/13 23:21:43 momjian Exp $ + * $Id: cost.h,v 1.18 1999/05/01 19:47:39 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -34,7 +34,7 @@ extern Cost cost_seqscan(int relid, int relpages, int reltuples); extern Cost cost_index(Oid indexid, int expected_indexpages, Cost selec, int relpages, int reltuples, int indexpages, int indextuples, bool is_injoin); -extern Cost cost_sort(List *pathkeys, int tuples, int width, bool noread); +extern Cost cost_sort(List *pathkeys, int tuples, int width); extern Cost cost_nestloop(Cost outercost, Cost innercost, int outertuples, int innertuples, int outerpages, bool is_indexjoin); extern Cost cost_mergejoin(Cost outercost, Cost innercost,