Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 834ddc6

Browse files
committed
Avoid considering both sort directions as equally useful for merging.
This doubles the planning workload for mergejoins while not actually accomplishing much. The only useful case is where one of the directions matches the query's ORDER BY request; therefore, put a thumb on the scales in that direction, and otherwise arbitrarily consider only the ASC direction. (This is a lot easier now than it would've been before 8.3, since we have more semantic knowledge embedded in PathKeys now.)
1 parent 5b5a70a commit 834ddc6

File tree

1 file changed

+45
-1
lines changed

1 file changed

+45
-1
lines changed

src/backend/optimizer/path/pathkeys.c

+45-1
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.85 2007/05/31 16:57:34 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.86 2007/10/27 05:45:43 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -49,6 +49,7 @@ static PathKey *make_pathkey_from_sortinfo(PlannerInfo *root,
4949
bool canonicalize);
5050
static Var *find_indexkey_var(PlannerInfo *root, RelOptInfo *rel,
5151
AttrNumber varattno);
52+
static bool right_merge_direction(PlannerInfo *root, PathKey *pathkey);
5253

5354

5455
/****************************************************************************
@@ -1242,6 +1243,13 @@ make_inner_pathkeys_for_merge(PlannerInfo *root,
12421243
* overoptimistic, since joinclauses that require different other relations
12431244
* might never be usable at the same time, but trying to be exact is likely
12441245
* to be more trouble than it's worth.
1246+
*
1247+
* To avoid doubling the number of mergejoin paths considered, we would like
1248+
* to consider only one of the two scan directions (ASC or DESC) as useful
1249+
* for merging for any given target column. The choice is arbitrary unless
1250+
* one of the directions happens to match an ORDER BY key, in which case
1251+
* that direction should be preferred, in hopes of avoiding a final sort step.
1252+
* right_merge_direction() implements this heuristic.
12451253
*/
12461254
int
12471255
pathkeys_useful_for_merging(PlannerInfo *root, RelOptInfo *rel, List *pathkeys)
@@ -1255,6 +1263,10 @@ pathkeys_useful_for_merging(PlannerInfo *root, RelOptInfo *rel, List *pathkeys)
12551263
bool matched = false;
12561264
ListCell *j;
12571265

1266+
/* If "wrong" direction, not useful for merging */
1267+
if (!right_merge_direction(root, pathkey))
1268+
break;
1269+
12581270
/*
12591271
* First look into the EquivalenceClass of the pathkey, to see if
12601272
* there are any members not yet joined to the rel. If so, it's
@@ -1301,6 +1313,38 @@ pathkeys_useful_for_merging(PlannerInfo *root, RelOptInfo *rel, List *pathkeys)
13011313
return useful;
13021314
}
13031315

1316+
/*
1317+
* right_merge_direction
1318+
* Check whether the pathkey embodies the preferred sort direction
1319+
* for merging its target column.
1320+
*/
1321+
static bool
1322+
right_merge_direction(PlannerInfo *root, PathKey *pathkey)
1323+
{
1324+
ListCell *l;
1325+
1326+
foreach(l, root->query_pathkeys)
1327+
{
1328+
PathKey *query_pathkey = (PathKey *) lfirst(l);
1329+
1330+
if (pathkey->pk_eclass == query_pathkey->pk_eclass &&
1331+
pathkey->pk_opfamily == query_pathkey->pk_opfamily)
1332+
{
1333+
/*
1334+
* Found a matching query sort column. Prefer this pathkey's
1335+
* direction iff it matches. Note that we ignore pk_nulls_first,
1336+
* which means that a sort might be needed anyway ... but we
1337+
* still want to prefer only one of the two possible directions,
1338+
* and we might as well use this one.
1339+
*/
1340+
return (pathkey->pk_strategy == query_pathkey->pk_strategy);
1341+
}
1342+
}
1343+
1344+
/* If no matching ORDER BY request, prefer the ASC direction */
1345+
return (pathkey->pk_strategy == BTLessStrategyNumber);
1346+
}
1347+
13041348
/*
13051349
* pathkeys_useful_for_ordering
13061350
* Count the number of pathkeys that are useful for meeting the

0 commit comments

Comments
 (0)