mirror of
https://github.com/postgres/postgres.git
synced 2025-05-21 15:54:08 +03:00
Avoid running build_index_pathkeys() in situations where there cannot
possibly be any useful pathkeys --- to wit, queries with neither any join clauses nor any ORDER BY request. It's nearly free to check for this case and it saves a useful fraction of the planning time for simple queries.
This commit is contained in:
parent
f97d4a267a
commit
fa92d21a48
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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)
|
SaOpControl saop_control)
|
||||||
{
|
{
|
||||||
Relids outer_relids = outer_rel ? outer_rel->relids : NULL;
|
Relids outer_relids = outer_rel ? outer_rel->relids : NULL;
|
||||||
|
bool possibly_useful_pathkeys = has_useful_pathkeys(root, rel);
|
||||||
List *result = NIL;
|
List *result = NIL;
|
||||||
List *all_clauses = NIL; /* not computed till needed */
|
List *all_clauses = NIL; /* not computed till needed */
|
||||||
ListCell *ilist;
|
ListCell *ilist;
|
||||||
@ -337,7 +338,8 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
* relevant unless we are at top level.
|
* relevant unless we are at top level.
|
||||||
*/
|
*/
|
||||||
index_is_ordered = OidIsValid(index->fwdsortop[0]);
|
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,
|
index_pathkeys = build_index_pathkeys(root, index,
|
||||||
ForwardScanDirection);
|
ForwardScanDirection);
|
||||||
@ -369,7 +371,8 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
* 4. If the index is ordered, a backwards scan might be
|
* 4. If the index is ordered, a backwards scan might be
|
||||||
* interesting. Again, this is only interesting at top level.
|
* 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,
|
index_pathkeys = build_index_pathkeys(root, index,
|
||||||
BackwardScanDirection);
|
BackwardScanDirection);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* Note: not safe to modify input list destructively, but we can avoid
|
||||||
* copying the list if we're not actually going to change it
|
* 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;
|
return pathkeys;
|
||||||
else
|
else
|
||||||
return list_truncate(list_copy(pathkeys), nuseful);
|
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 */
|
||||||
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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,
|
extern List *truncate_useless_pathkeys(PlannerInfo *root,
|
||||||
RelOptInfo *rel,
|
RelOptInfo *rel,
|
||||||
List *pathkeys);
|
List *pathkeys);
|
||||||
|
extern bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel);
|
||||||
|
|
||||||
#endif /* PATHS_H */
|
#endif /* PATHS_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user