From 1d5e7a6f46f799628392fc4a024a3d61e3dd1630 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 22 Mar 2000 22:08:35 +0000 Subject: 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. --- src/include/nodes/relation.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/include/nodes') diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index ac6dc764ce..f01877a9e8 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: relation.h,v 1.45 2000/02/18 23:47:17 tgl Exp $ + * $Id: relation.h,v 1.46 2000/03/22 22:08:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -252,6 +252,12 @@ typedef struct Path * as the inner path of a nestloop join. These paths have indexquals * that refer to values of other rels, so those other rels must be * included in the outer joinrel in order to make a usable join. + * + * 'rows' is the estimated result tuple count for the indexscan. This + * is the same as path.parent->rows for a simple indexscan, but it is + * different for a nestloop inner path, because the additional indexquals + * coming from join clauses make the scan more selective than the parent + * rel's restrict clauses alone would do. *---------- */ typedef struct IndexPath @@ -260,7 +266,8 @@ typedef struct IndexPath List *indexid; List *indexqual; ScanDirection indexscandir; - Relids joinrelids; /* other rels mentioned in indexqual */ + Relids joinrelids; /* other rels mentioned in indexqual */ + double rows; /* estimated number of result tuples */ } IndexPath; typedef struct TidPath -- cgit v1.2.1