Skip to content

Commit 0ee53b5

Browse files
committed
Don't return an overoptimistic result from join_in_selectivity when
we have detected that an IN subquery must return unique results.
1 parent 864412f commit 0ee53b5

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

src/backend/optimizer/path/costsize.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
* Portions Copyright (c) 1994, Regents of the University of California
5050
*
5151
* IDENTIFICATION
52-
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.122 2004/01/06 04:31:01 tgl Exp $
52+
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.123 2004/01/19 03:52:28 tgl Exp $
5353
*
5454
*-------------------------------------------------------------------------
5555
*/
@@ -763,9 +763,7 @@ cost_nestloop(NestPath *path, Query *root)
763763
* an outer tuple as soon as we have one match. Account for the
764764
* effects of this by scaling down the cost estimates in proportion to
765765
* the JOIN_IN selectivity. (This assumes that all the quals
766-
* attached to the join are IN quals, which should be true.) This would
767-
* probably be the wrong approach if an input path is a UniquePath, but
768-
* we'd never have that with JOIN_IN join type.
766+
* attached to the join are IN quals, which should be true.)
769767
*/
770768
joininfactor = join_in_selectivity(path, root);
771769

@@ -1001,9 +999,7 @@ cost_mergejoin(MergePath *path, Query *root)
1001999
* for an outer tuple as soon as we have one match. Account for the
10021000
* effects of this by scaling down the cost estimates in proportion to
10031001
* the expected output size. (This assumes that all the quals
1004-
* attached to the join are IN quals, which should be true.) This would
1005-
* probably be the wrong approach if an input path is a UniquePath, but
1006-
* we'd never have that with JOIN_IN join type.
1002+
* attached to the join are IN quals, which should be true.)
10071003
*/
10081004
joininfactor = join_in_selectivity(&path->jpath, root);
10091005

@@ -1208,9 +1204,7 @@ cost_hashjoin(HashPath *path, Query *root)
12081204
* an outer tuple as soon as we have one match. Account for the
12091205
* effects of this by scaling down the cost estimates in proportion to
12101206
* the expected output size. (This assumes that all the quals
1211-
* attached to the join are IN quals, which should be true.) This would
1212-
* probably be the wrong approach if an input path is a UniquePath, but
1213-
* we'd never have that with JOIN_IN join type.
1207+
* attached to the join are IN quals, which should be true.)
12141208
*/
12151209
joininfactor = join_in_selectivity(&path->jpath, root);
12161210

@@ -1779,12 +1773,31 @@ set_joinrel_size_estimates(Query *root, RelOptInfo *rel,
17791773
static Selectivity
17801774
join_in_selectivity(JoinPath *path, Query *root)
17811775
{
1776+
RelOptInfo *innerrel;
1777+
UniquePath *innerunique;
17821778
Selectivity selec;
17831779
double nrows;
17841780

1781+
/* Return 1.0 whenever it's not JOIN_IN */
17851782
if (path->jointype != JOIN_IN)
17861783
return 1.0;
17871784

1785+
/*
1786+
* Return 1.0 if the inner side is already known unique. The case where
1787+
* the inner path is already a UniquePath probably cannot happen in
1788+
* current usage, but check it anyway for completeness. The interesting
1789+
* case is where we've determined the inner relation itself is unique,
1790+
* which we can check by looking at the rows estimate for its UniquePath.
1791+
*/
1792+
if (IsA(path->innerjoinpath, UniquePath))
1793+
return 1.0;
1794+
innerrel = path->innerjoinpath->parent;
1795+
innerunique = create_unique_path(root,
1796+
innerrel,
1797+
innerrel->cheapest_total_path);
1798+
if (innerunique->rows >= innerrel->rows)
1799+
return 1.0;
1800+
17881801
/*
17891802
* Compute same result set_joinrel_size_estimates would compute
17901803
* for JOIN_INNER. Note that we use the input rels' absolute size
@@ -1796,8 +1809,7 @@ join_in_selectivity(JoinPath *path, Query *root)
17961809
path->joinrestrictinfo,
17971810
0,
17981811
JOIN_INNER);
1799-
nrows = path->outerjoinpath->parent->rows *
1800-
path->innerjoinpath->parent->rows * selec;
1812+
nrows = path->outerjoinpath->parent->rows * innerrel->rows * selec;
18011813

18021814
nrows = clamp_row_est(nrows);
18031815

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