diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 176f2a6638..243888b58d 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.219 2007/04/06 22:33:42 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.220 2007/04/15 20:09:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -251,6 +251,7 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel, SaOpControl saop_control) { Relids outer_relids = outer_rel ? outer_rel->relids : NULL; + bool possibly_useful_pathkeys = has_useful_pathkeys(root, rel); List *result = NIL; List *all_clauses = NIL; /* not computed till needed */ ListCell *ilist; @@ -337,7 +338,8 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel, * relevant unless we are at top level. */ index_is_ordered = OidIsValid(index->fwdsortop[0]); - if (index_is_ordered && istoplevel && outer_rel == NULL) + if (index_is_ordered && possibly_useful_pathkeys && + istoplevel && outer_rel == NULL) { index_pathkeys = build_index_pathkeys(root, index, ForwardScanDirection); @@ -369,7 +371,8 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel, * 4. If the index is ordered, a backwards scan might be * interesting. Again, this is only interesting at top level. */ - if (index_is_ordered && istoplevel && outer_rel == NULL) + if (index_is_ordered && possibly_useful_pathkeys && + istoplevel && outer_rel == NULL) { index_pathkeys = build_index_pathkeys(root, index, BackwardScanDirection); diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index 37c5e35c23..7a2aaa48f6 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -11,7 +11,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.83 2007/01/21 00:57:15 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.84 2007/04/15 20:09:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1327,8 +1327,35 @@ truncate_useless_pathkeys(PlannerInfo *root, * Note: not safe to modify input list destructively, but we can avoid * copying the list if we're not actually going to change it */ - if (nuseful == list_length(pathkeys)) + if (nuseful == 0) + return NIL; + else if (nuseful == list_length(pathkeys)) return pathkeys; else return list_truncate(list_copy(pathkeys), nuseful); } + +/* + * has_useful_pathkeys + * Detect whether the specified rel could have any pathkeys that are + * useful according to truncate_useless_pathkeys(). + * + * This is a cheap test that lets us skip building pathkeys at all in very + * simple queries. It's OK to err in the direction of returning "true" when + * there really aren't any usable pathkeys, but erring in the other direction + * is bad --- so keep this in sync with the routines above! + * + * We could make the test more complex, for example checking to see if any of + * the joinclauses are really mergejoinable, but that likely wouldn't win + * often enough to repay the extra cycles. Queries with neither a join nor + * a sort are reasonably common, though, so this much work seems worthwhile. + */ +bool +has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel) +{ + if (rel->joininfo != NIL || rel->has_eclass_joins) + return true; /* might be able to use pathkeys for merging */ + if (root->query_pathkeys != NIL) + return true; /* might be able to use them for ordering */ + return false; /* definitely useless */ +} diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index 6b985e24cd..c7b8d8c752 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.96 2007/02/16 00:14:01 tgl Exp $ + * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.97 2007/04/15 20:09:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -176,5 +176,6 @@ extern int pathkeys_useful_for_ordering(PlannerInfo *root, List *pathkeys); extern List *truncate_useless_pathkeys(PlannerInfo *root, RelOptInfo *rel, List *pathkeys); +extern bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel); #endif /* PATHS_H */