*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
* 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);
* 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);
* 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 $
*
*-------------------------------------------------------------------------
*/
* 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 */
+}
* 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 $
*
*-------------------------------------------------------------------------
*/
extern List *truncate_useless_pathkeys(PlannerInfo *root,
RelOptInfo *rel,
List *pathkeys);
+extern bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel);
#endif /* PATHS_H */