Clean up cost_sort some more: most callers were double-counting
the cost of reading the source data.
This commit is contained in:
parent
87d95ca04d
commit
605d84941d
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* cost_sort
|
||||||
* Determines and returns the cost of sorting a relation by considering
|
* 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)
|
* disk = (p lg p)
|
||||||
* cpu = *CPU-PAGE-WEIGHT* * (t lg t)
|
* 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
|
* 'pathkeys' is a list of sort keys
|
||||||
* 'tuples' is the number of tuples in the relation
|
* 'tuples' is the number of tuples in the relation
|
||||||
* 'width' is the average tuple width in bytes
|
* '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
|
* 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...
|
* 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.
|
* Returns a flonum.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
Cost
|
Cost
|
||||||
cost_sort(List *pathkeys, int tuples, int width, bool noread)
|
cost_sort(List *pathkeys, int tuples, int width)
|
||||||
{
|
{
|
||||||
Cost temp = 0;
|
Cost temp = 0;
|
||||||
int npages = page_size(tuples, width);
|
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,
|
/* 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)...
|
* even if passed-in tuple count is zero. Besides, mustn't do log(0)...
|
||||||
*/
|
*/
|
||||||
|
if (tuples <= 0)
|
||||||
|
tuples = 1;
|
||||||
if (npages <= 0)
|
if (npages <= 0)
|
||||||
npages = 1;
|
npages = 1;
|
||||||
|
|
||||||
|
@ -210,13 +207,10 @@ cost_sort(List *pathkeys, int tuples, int width, bool noread)
|
||||||
temp += npages * log_npages;
|
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
|
* merges
|
||||||
*/
|
*/
|
||||||
temp += _cpu_page_wight_ * tuples * log_npages;
|
temp += _cpu_page_wight_ * tuples * base_log((double) tuples, 2.0);
|
||||||
|
|
||||||
if (!noread)
|
|
||||||
temp += cost_seqscan(_NONAME_RELATION_ID_, npages, tuples);
|
|
||||||
|
|
||||||
Assert(temp > 0);
|
Assert(temp > 0);
|
||||||
|
|
||||||
|
@ -282,7 +276,8 @@ cost_nestloop(Cost outercost,
|
||||||
* 'outercost' and 'innercost' are the (disk+cpu) costs of scanning the
|
* 'outercost' and 'innercost' are the (disk+cpu) costs of scanning the
|
||||||
* outer and inner relations
|
* outer and inner relations
|
||||||
* 'outersortkeys' and 'innersortkeys' are lists of the keys to be used
|
* '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
|
* 'outertuples' and 'innertuples' are the number of tuples in the outer
|
||||||
* and inner relations
|
* and inner relations
|
||||||
* 'outerwidth' and 'innerwidth' are the (typical) widths (in bytes)
|
* 'outerwidth' and 'innerwidth' are the (typical) widths (in bytes)
|
||||||
|
@ -309,9 +304,9 @@ cost_mergejoin(Cost outercost,
|
||||||
temp += outercost;
|
temp += outercost;
|
||||||
temp += innercost;
|
temp += innercost;
|
||||||
if (outersortkeys) /* do we need to sort? */
|
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? */
|
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);
|
temp += _cpu_page_wight_ * (outersize + innersize);
|
||||||
|
|
||||||
Assert(temp >= 0);
|
Assert(temp >= 0);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 <
|
(mergeinnerpath->path_cost <
|
||||||
(cheapest_inner->path_cost +
|
(cheapest_inner->path_cost +
|
||||||
cost_sort(matchedJoinKeys, innerrel->size,
|
cost_sort(matchedJoinKeys, innerrel->size,
|
||||||
innerrel->width, false))));
|
innerrel->width))));
|
||||||
if (!path_is_cheaper_than_sort)
|
if (!path_is_cheaper_than_sort)
|
||||||
{
|
{
|
||||||
varkeys = make_pathkeys_from_joinkeys(matchedJoinKeys,
|
varkeys = make_pathkeys_from_joinkeys(matchedJoinKeys,
|
||||||
|
@ -464,8 +464,7 @@ match_unsorted_inner(RelOptInfo *joinrel,
|
||||||
if (clauses && matchedJoinKeys)
|
if (clauses && matchedJoinKeys)
|
||||||
{
|
{
|
||||||
temp1 = outerrel->cheapestpath->path_cost +
|
temp1 = outerrel->cheapestpath->path_cost +
|
||||||
cost_sort(matchedJoinKeys, outerrel->size, outerrel->width,
|
cost_sort(matchedJoinKeys, outerrel->size, outerrel->width);
|
||||||
false);
|
|
||||||
|
|
||||||
temp2 = (bool) (FLOAT_IS_ZERO(innerpath->outerjoincost)
|
temp2 = (bool) (FLOAT_IS_ZERO(innerpath->outerjoincost)
|
||||||
|| (innerpath->outerjoincost > temp1));
|
|| (innerpath->outerjoincost > temp1));
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
Plan *plan = &node->plan;
|
||||||
|
|
||||||
copy_costsize(plan, lefttree);
|
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->state = (EState *) NULL;
|
||||||
plan->targetlist = tlist;
|
plan->targetlist = tlist;
|
||||||
plan->qual = NIL;
|
plan->qual = NIL;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* 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,
|
extern Cost cost_index(Oid indexid, int expected_indexpages, Cost selec,
|
||||||
int relpages, int reltuples, int indexpages,
|
int relpages, int reltuples, int indexpages,
|
||||||
int indextuples, bool is_injoin);
|
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,
|
extern Cost cost_nestloop(Cost outercost, Cost innercost, int outertuples,
|
||||||
int innertuples, int outerpages, bool is_indexjoin);
|
int innertuples, int outerpages, bool is_indexjoin);
|
||||||
extern Cost cost_mergejoin(Cost outercost, Cost innercost,
|
extern Cost cost_mergejoin(Cost outercost, Cost innercost,
|
||||||
|
|
Loading…
Reference in New Issue