1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

Repair logic flaw in cost estimator: cost_nestloop() was estimating CPU

costs using the inner path's parent->rows count as the number of tuples
processed per inner scan iteration.  This is wrong when we are using an
inner indexscan with indexquals based on join clauses, because the rows
count in a Relation node reflects the selectivity of the restriction
clauses for that rel only.  Upshot was that if join clause was very
selective, we'd drastically overestimate the true cost of the join.
Fix is to calculate correct output-rows estimate for an inner indexscan
when the IndexPath node is created and save it in the path node.
Change of path node doesn't require initdb, since path nodes don't
appear in saved rules.
This commit is contained in:
Tom Lane
2000-03-22 22:08:35 +00:00
parent d825e55c13
commit 1d5e7a6f46
11 changed files with 83 additions and 63 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.61 2000/02/18 23:47:30 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.62 2000/03/22 22:08:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -337,8 +337,16 @@ create_index_path(Query *root,
*/
pathnode->indexid = lconsi(index->indexoid, NIL);
pathnode->indexqual = lcons(indexquals, NIL);
pathnode->indexscandir = indexscandir;
/*
* This routine is only used to generate "standalone" indexpaths,
* not nestloop inner indexpaths. So joinrelids is always NIL
* and the number of rows is the same as the parent rel's estimate.
*/
pathnode->joinrelids = NIL; /* no join clauses here */
pathnode->rows = rel->rows;
cost_index(&pathnode->path, root, rel, index, indexquals, false);
@ -400,8 +408,7 @@ create_nestloop_path(RelOptInfo *joinrel,
pathnode->joinrestrictinfo = restrict_clauses;
pathnode->path.pathkeys = pathkeys;
cost_nestloop(&pathnode->path, outer_path, inner_path,
restrict_clauses, IsA(inner_path, IndexPath));
cost_nestloop(&pathnode->path, outer_path, inner_path, restrict_clauses);
return pathnode;
}