Skip to content

Commit fa92d21

Browse files
committed
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.
1 parent f97d4a2 commit fa92d21

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

src/backend/optimizer/path/indxpath.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.219 2007/04/06 22:33:42 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.220 2007/04/15 20:09:28 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -251,6 +251,7 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
251251
SaOpControl saop_control)
252252
{
253253
Relids outer_relids = outer_rel ? outer_rel->relids : NULL;
254+
bool possibly_useful_pathkeys = has_useful_pathkeys(root, rel);
254255
List *result = NIL;
255256
List *all_clauses = NIL; /* not computed till needed */
256257
ListCell *ilist;
@@ -337,7 +338,8 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
337338
* relevant unless we are at top level.
338339
*/
339340
index_is_ordered = OidIsValid(index->fwdsortop[0]);
340-
if (index_is_ordered && istoplevel && outer_rel == NULL)
341+
if (index_is_ordered && possibly_useful_pathkeys &&
342+
istoplevel && outer_rel == NULL)
341343
{
342344
index_pathkeys = build_index_pathkeys(root, index,
343345
ForwardScanDirection);
@@ -369,7 +371,8 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
369371
* 4. If the index is ordered, a backwards scan might be
370372
* interesting. Again, this is only interesting at top level.
371373
*/
372-
if (index_is_ordered && istoplevel && outer_rel == NULL)
374+
if (index_is_ordered && possibly_useful_pathkeys &&
375+
istoplevel && outer_rel == NULL)
373376
{
374377
index_pathkeys = build_index_pathkeys(root, index,
375378
BackwardScanDirection);

src/backend/optimizer/path/pathkeys.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.83 2007/01/21 00:57:15 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.84 2007/04/15 20:09:28 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -1327,8 +1327,35 @@ truncate_useless_pathkeys(PlannerInfo *root,
13271327
* Note: not safe to modify input list destructively, but we can avoid
13281328
* copying the list if we're not actually going to change it
13291329
*/
1330-
if (nuseful == list_length(pathkeys))
1330+
if (nuseful == 0)
1331+
return NIL;
1332+
else if (nuseful == list_length(pathkeys))
13311333
return pathkeys;
13321334
else
13331335
return list_truncate(list_copy(pathkeys), nuseful);
13341336
}
1337+
1338+
/*
1339+
* has_useful_pathkeys
1340+
* Detect whether the specified rel could have any pathkeys that are
1341+
* useful according to truncate_useless_pathkeys().
1342+
*
1343+
* This is a cheap test that lets us skip building pathkeys at all in very
1344+
* simple queries. It's OK to err in the direction of returning "true" when
1345+
* there really aren't any usable pathkeys, but erring in the other direction
1346+
* is bad --- so keep this in sync with the routines above!
1347+
*
1348+
* We could make the test more complex, for example checking to see if any of
1349+
* the joinclauses are really mergejoinable, but that likely wouldn't win
1350+
* often enough to repay the extra cycles. Queries with neither a join nor
1351+
* a sort are reasonably common, though, so this much work seems worthwhile.
1352+
*/
1353+
bool
1354+
has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel)
1355+
{
1356+
if (rel->joininfo != NIL || rel->has_eclass_joins)
1357+
return true; /* might be able to use pathkeys for merging */
1358+
if (root->query_pathkeys != NIL)
1359+
return true; /* might be able to use them for ordering */
1360+
return false; /* definitely useless */
1361+
}

src/include/optimizer/paths.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.96 2007/02/16 00:14:01 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.97 2007/04/15 20:09:28 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -176,5 +176,6 @@ extern int pathkeys_useful_for_ordering(PlannerInfo *root, List *pathkeys);
176176
extern List *truncate_useless_pathkeys(PlannerInfo *root,
177177
RelOptInfo *rel,
178178
List *pathkeys);
179+
extern bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel);
179180

180181
#endif /* PATHS_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy