diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-05-22 01:40:42 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-05-22 01:40:42 +0000 |
commit | 107cbb2b9011e7179427aa67b35a97b49d572f6c (patch) | |
tree | 95709ca1fac67db588e3093d61bc647a4b4ce4b2 /src/include | |
parent | 06df9a69e83396da87083bf5810855547b3ffff4 (diff) |
Fix best_inner_indexscan to return both the cheapest-total-cost and
cheapest-startup-cost innerjoin indexscans, and make joinpath.c consider
both of these (when different) as the inside of a nestloop join. The
original design was based on the assumption that indexscan paths always
have negligible startup cost, and so total cost is the only important
figure of merit; an assumption that's obviously broken by bitmap
indexscans. This oversight could lead to choosing poor plans in cases
where fast-start behavior is more important than total cost, such as
LIMIT and IN queries. 8.1-vintage brain fade exposed by an example from
Chuck D.
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/nodes/relation.h | 13 | ||||
-rw-r--r-- | src/include/optimizer/paths.h | 7 |
2 files changed, 11 insertions, 9 deletions
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index dcbcc6b3cee..ad31d536e0b 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.128.2.1 2007/02/16 20:57:26 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.128.2.2 2007/05/22 01:40:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -806,20 +806,20 @@ typedef struct RestrictInfo * relation includes all other relids appearing in those joinclauses. * The set of usable joinclauses, and thus the best inner indexscan, * thus varies depending on which outer relation we consider; so we have - * to recompute the best such path for every join. To avoid lots of + * to recompute the best such paths for every join. To avoid lots of * redundant computation, we cache the results of such searches. For * each relation we compute the set of possible otherrelids (all relids * appearing in joinquals that could become indexquals for this table). * Two outer relations whose relids have the same intersection with this * set will have the same set of available joinclauses and thus the same - * best inner indexscan for the inner relation. By taking the intersection + * best inner indexscans for the inner relation. By taking the intersection * before scanning the cache, we avoid recomputing when considering * join rels that differ only by the inclusion of irrelevant other rels. * * The search key also includes a bool showing whether the join being * considered is an outer join. Since we constrain the join order for * outer joins, I believe that this bool can only have one possible value - * for any particular base relation; but store it anyway to avoid confusion. + * for any particular lookup key; but store it anyway to avoid confusion. */ typedef struct InnerIndexscanInfo @@ -828,8 +828,9 @@ typedef struct InnerIndexscanInfo /* The lookup key: */ Relids other_relids; /* a set of relevant other relids */ bool isouterjoin; /* true if join is outer */ - /* Best path for this lookup key: */ - Path *best_innerpath; /* best inner indexscan, or NULL if none */ + /* Best paths for this lookup key (NULL if no available indexscans): */ + Path *cheapest_startup_innerpath; /* cheapest startup cost */ + Path *cheapest_total_innerpath; /* cheapest total cost */ } InnerIndexscanInfo; /* diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index 39aff9fc436..9b3eaaf4300 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.93.2.1 2007/02/16 00:14:08 tgl Exp $ + * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.93.2.2 2007/05/22 01:40:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -45,8 +45,9 @@ extern void create_index_paths(PlannerInfo *root, RelOptInfo *rel); extern List *generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel, List *clauses, List *outer_clauses, RelOptInfo *outer_rel); -extern Path *best_inner_indexscan(PlannerInfo *root, RelOptInfo *rel, - RelOptInfo *outer_rel, JoinType jointype); +extern void best_inner_indexscan(PlannerInfo *root, RelOptInfo *rel, + RelOptInfo *outer_rel, JoinType jointype, + Path **cheapest_startup, Path **cheapest_total); extern List *group_clauses_by_indexkey(IndexOptInfo *index, List *clauses, List *outer_clauses, Relids outer_relids, |