5454 * Portions Copyright (c) 1994, Regents of the University of California
5555 *
5656 * IDENTIFICATION
57- * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.207 2009/04/17 15:33:33 tgl Exp $
57+ * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.208 2009/05/09 22:51:41 tgl Exp $
5858 *
5959 *-------------------------------------------------------------------------
6060 */
7171#include "optimizer/pathnode.h"
7272#include "optimizer/placeholder.h"
7373#include "optimizer/planmain.h"
74+ #include "optimizer/restrictinfo.h"
7475#include "parser/parsetree.h"
7576#include "utils/lsyscache.h"
7677#include "utils/selfuncs.h"
@@ -119,6 +120,11 @@ static MergeScanSelCache *cached_scansel(PlannerInfo *root,
119120RestrictInfo * rinfo ,
120121PathKey * pathkey );
121122static bool cost_qual_eval_walker (Node * node ,cost_qual_eval_context * context );
123+ static bool adjust_semi_join (PlannerInfo * root ,JoinPath * path ,
124+ SpecialJoinInfo * sjinfo ,
125+ Selectivity * outer_match_frac ,
126+ Selectivity * match_count ,
127+ bool * indexed_join_quals );
122128static double approx_tuple_count (PlannerInfo * root ,JoinPath * path ,
123129List * quals );
124130static void set_rel_width (PlannerInfo * root ,RelOptInfo * rel );
@@ -1394,11 +1400,15 @@ cost_nestloop(NestPath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
13941400Path * inner_path = path -> innerjoinpath ;
13951401Cost startup_cost = 0 ;
13961402Cost run_cost = 0 ;
1403+ Cost inner_run_cost ;
13971404Cost cpu_per_tuple ;
13981405QualCost restrict_qual_cost ;
13991406double outer_path_rows = PATH_ROWS (outer_path );
14001407double inner_path_rows = nestloop_inner_path_rows (inner_path );
14011408double ntuples ;
1409+ Selectivity outer_match_frac ;
1410+ Selectivity match_count ;
1411+ bool indexed_join_quals ;
14021412
14031413if (!enable_nestloop )
14041414startup_cost += disable_cost ;
@@ -1428,13 +1438,66 @@ cost_nestloop(NestPath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
14281438 */
14291439run_cost += (outer_path_rows - 1 )* inner_path -> startup_cost ;
14301440}
1431- run_cost += outer_path_rows *
1432- (inner_path -> total_cost - inner_path -> startup_cost );
1441+ inner_run_cost = inner_path -> total_cost - inner_path -> startup_cost ;
14331442
1434- /*
1435- * Compute number of tuples processed (not number emitted!)
1436- */
1437- ntuples = outer_path_rows * inner_path_rows ;
1443+ if (adjust_semi_join (root ,path ,sjinfo ,
1444+ & outer_match_frac ,
1445+ & match_count ,
1446+ & indexed_join_quals ))
1447+ {
1448+ double outer_matched_rows ;
1449+ Selectivity inner_scan_frac ;
1450+
1451+ /*
1452+ * SEMI or ANTI join: executor will stop after first match.
1453+ *
1454+ * For an outer-rel row that has at least one match, we can expect the
1455+ * inner scan to stop after a fraction 1/(match_count+1) of the inner
1456+ * rows, if the matches are evenly distributed. Since they probably
1457+ * aren't quite evenly distributed, we apply a fuzz factor of 2.0 to
1458+ * that fraction. (If we used a larger fuzz factor, we'd have to
1459+ * clamp inner_scan_frac to at most 1.0; but since match_count is at
1460+ * least 1, no such clamp is needed now.)
1461+ */
1462+ outer_matched_rows = rint (outer_path_rows * outer_match_frac );
1463+ inner_scan_frac = 2.0 / (match_count + 1.0 );
1464+
1465+ /* Add inner run cost for outer tuples having matches */
1466+ run_cost += outer_matched_rows * inner_run_cost * inner_scan_frac ;
1467+
1468+ /* Compute number of tuples processed (not number emitted!) */
1469+ ntuples = outer_matched_rows * inner_path_rows * inner_scan_frac ;
1470+
1471+ /*
1472+ * For unmatched outer-rel rows, there are two cases. If the inner
1473+ * path is an indexscan using all the joinquals as indexquals, then
1474+ * an unmatched row results in an indexscan returning no rows, which
1475+ * is probably quite cheap. We estimate this case as the same cost
1476+ * to return the first tuple of a nonempty scan. Otherwise, the
1477+ * executor will have to scan the whole inner rel; not so cheap.
1478+ */
1479+ if (indexed_join_quals )
1480+ {
1481+ run_cost += (outer_path_rows - outer_matched_rows )*
1482+ inner_run_cost /inner_path_rows ;
1483+ /* We won't be evaluating any quals at all for these rows */
1484+ }
1485+ else
1486+ {
1487+ run_cost += (outer_path_rows - outer_matched_rows )*
1488+ inner_run_cost ;
1489+ ntuples += (outer_path_rows - outer_matched_rows )*
1490+ inner_path_rows ;
1491+ }
1492+ }
1493+ else
1494+ {
1495+ /* Normal case; we'll scan whole input rel for each outer row */
1496+ run_cost += outer_path_rows * inner_run_cost ;
1497+
1498+ /* Compute number of tuples processed (not number emitted!) */
1499+ ntuples = outer_path_rows * inner_path_rows ;
1500+ }
14381501
14391502/* CPU costs */
14401503cost_qual_eval (& restrict_qual_cost ,path -> joinrestrictinfo ,root );
@@ -1731,6 +1794,9 @@ cost_mergejoin(MergePath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
17311794 * cpu_tuple_cost plus the cost of evaluating additional restriction
17321795 * clauses that are to be applied at the join.(This is pessimistic since
17331796 * not all of the quals may get evaluated at each tuple.)
1797+ *
1798+ * Note: we could adjust for SEMI/ANTI joins skipping some qual evaluations
1799+ * here, but it's probably not worth the trouble.
17341800 */
17351801startup_cost += qp_qual_cost .startup ;
17361802cpu_per_tuple = cpu_tuple_cost + qp_qual_cost .per_tuple ;
@@ -1824,6 +1890,8 @@ cost_hashjoin(HashPath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
18241890int num_skew_mcvs ;
18251891double virtualbuckets ;
18261892Selectivity innerbucketsize ;
1893+ Selectivity outer_match_frac ;
1894+ Selectivity match_count ;
18271895ListCell * hcl ;
18281896
18291897if (!enable_hashjoin )
@@ -1838,12 +1906,6 @@ cost_hashjoin(HashPath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
18381906qp_qual_cost .startup -= hash_qual_cost .startup ;
18391907qp_qual_cost .per_tuple -= hash_qual_cost .per_tuple ;
18401908
1841- /*
1842- * Get approx # tuples passing the hashquals. We use approx_tuple_count
1843- * here because we need an estimate done with JOIN_INNER semantics.
1844- */
1845- hashjointuples = approx_tuple_count (root ,& path -> jpath ,hashclauses );
1846-
18471909/* cost of source data */
18481910startup_cost += outer_path -> startup_cost ;
18491911run_cost += outer_path -> total_cost - outer_path -> startup_cost ;
@@ -1970,18 +2032,78 @@ cost_hashjoin(HashPath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
19702032
19712033/* CPU costs */
19722034
1973- /*
1974- * The number of tuple comparisons needed is the number of outer tuples
1975- * times the typical number of tuples in a hash bucket, which is the inner
1976- * relation size times its bucketsize fraction. At each one, we need to
1977- * evaluate the hashjoin quals. But actually, charging the full qual eval
1978- * cost at each tuple is pessimistic, since we don't evaluate the quals
1979- * unless the hash values match exactly. For lack of a better idea, halve
1980- * the cost estimate to allow for that.
1981- */
1982- startup_cost += hash_qual_cost .startup ;
1983- run_cost += hash_qual_cost .per_tuple *
1984- outer_path_rows * clamp_row_est (inner_path_rows * innerbucketsize )* 0.5 ;
2035+ if (adjust_semi_join (root ,& path -> jpath ,sjinfo ,
2036+ & outer_match_frac ,
2037+ & match_count ,
2038+ NULL ))
2039+ {
2040+ double outer_matched_rows ;
2041+ Selectivity inner_scan_frac ;
2042+
2043+ /*
2044+ * SEMI or ANTI join: executor will stop after first match.
2045+ *
2046+ * For an outer-rel row that has at least one match, we can expect the
2047+ * bucket scan to stop after a fraction 1/(match_count+1) of the
2048+ * bucket's rows, if the matches are evenly distributed. Since they
2049+ * probably aren't quite evenly distributed, we apply a fuzz factor of
2050+ * 2.0 to that fraction. (If we used a larger fuzz factor, we'd have
2051+ * to clamp inner_scan_frac to at most 1.0; but since match_count is
2052+ * at least 1, no such clamp is needed now.)
2053+ */
2054+ outer_matched_rows = rint (outer_path_rows * outer_match_frac );
2055+ inner_scan_frac = 2.0 / (match_count + 1.0 );
2056+
2057+ startup_cost += hash_qual_cost .startup ;
2058+ run_cost += hash_qual_cost .per_tuple * outer_matched_rows *
2059+ clamp_row_est (inner_path_rows * innerbucketsize * inner_scan_frac )* 0.5 ;
2060+
2061+ /*
2062+ * For unmatched outer-rel rows, the picture is quite a lot different.
2063+ * In the first place, there is no reason to assume that these rows
2064+ * preferentially hit heavily-populated buckets; instead assume they
2065+ * are uncorrelated with the inner distribution and so they see an
2066+ * average bucket size of inner_path_rows / virtualbuckets. In the
2067+ * second place, it seems likely that they will have few if any
2068+ * exact hash-code matches and so very few of the tuples in the
2069+ * bucket will actually require eval of the hash quals. We don't
2070+ * have any good way to estimate how many will, but for the moment
2071+ * assume that the effective cost per bucket entry is one-tenth what
2072+ * it is for matchable tuples.
2073+ */
2074+ run_cost += hash_qual_cost .per_tuple *
2075+ (outer_path_rows - outer_matched_rows )*
2076+ clamp_row_est (inner_path_rows /virtualbuckets )* 0.05 ;
2077+
2078+ /* Get # of tuples that will pass the basic join */
2079+ if (path -> jpath .jointype == JOIN_SEMI )
2080+ hashjointuples = outer_matched_rows ;
2081+ else
2082+ hashjointuples = outer_path_rows - outer_matched_rows ;
2083+ }
2084+ else
2085+ {
2086+ /*
2087+ * The number of tuple comparisons needed is the number of outer
2088+ * tuples times the typical number of tuples in a hash bucket, which
2089+ * is the inner relation size times its bucketsize fraction. At each
2090+ * one, we need to evaluate the hashjoin quals. But actually,
2091+ * charging the full qual eval cost at each tuple is pessimistic,
2092+ * since we don't evaluate the quals unless the hash values match
2093+ * exactly. For lack of a better idea, halve the cost estimate to
2094+ * allow for that.
2095+ */
2096+ startup_cost += hash_qual_cost .startup ;
2097+ run_cost += hash_qual_cost .per_tuple * outer_path_rows *
2098+ clamp_row_est (inner_path_rows * innerbucketsize )* 0.5 ;
2099+
2100+ /*
2101+ * Get approx # tuples passing the hashquals. We use
2102+ * approx_tuple_count here because we need an estimate done with
2103+ * JOIN_INNER semantics.
2104+ */
2105+ hashjointuples = approx_tuple_count (root ,& path -> jpath ,hashclauses );
2106+ }
19852107
19862108/*
19872109 * For each tuple that gets through the hashjoin proper, we charge
@@ -2320,6 +2442,156 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
23202442}
23212443
23222444
2445+ /*
2446+ * adjust_semi_join
2447+ * Estimate how much of the inner input a SEMI or ANTI join
2448+ * can be expected to scan.
2449+ *
2450+ * In a hash or nestloop SEMI/ANTI join, the executor will stop scanning
2451+ * inner rows as soon as it finds a match to the current outer row.
2452+ * We should therefore adjust some of the cost components for this effect.
2453+ * This function computes some estimates needed for these adjustments.
2454+ *
2455+ * 'path' is already filled in except for the cost fields
2456+ * 'sjinfo' is extra info about the join for selectivity estimation
2457+ *
2458+ * Returns TRUE if this is a SEMI or ANTI join, FALSE if not.
2459+ *
2460+ * Output parameters (set only in TRUE-result case):
2461+ * *outer_match_frac is set to the fraction of the outer tuples that are
2462+ *expected to have at least one match.
2463+ * *match_count is set to the average number of matches expected for
2464+ *outer tuples that have at least one match.
2465+ * *indexed_join_quals is set to TRUE if all the joinquals are used as
2466+ *inner index quals, FALSE if not.
2467+ *
2468+ * indexed_join_quals can be passed as NULL if that information is not
2469+ * relevant (it is only useful for the nestloop case).
2470+ */
2471+ static bool
2472+ adjust_semi_join (PlannerInfo * root ,JoinPath * path ,SpecialJoinInfo * sjinfo ,
2473+ Selectivity * outer_match_frac ,
2474+ Selectivity * match_count ,
2475+ bool * indexed_join_quals )
2476+ {
2477+ JoinType jointype = path -> jointype ;
2478+ Selectivity jselec ;
2479+ Selectivity nselec ;
2480+ Selectivity avgmatch ;
2481+ SpecialJoinInfo norm_sjinfo ;
2482+ List * joinquals ;
2483+ ListCell * l ;
2484+
2485+ /* Fall out if it's not JOIN_SEMI or JOIN_ANTI */
2486+ if (jointype != JOIN_SEMI && jointype != JOIN_ANTI )
2487+ return false;
2488+
2489+ /*
2490+ * Note: it's annoying to repeat this selectivity estimation on each call,
2491+ * when the joinclause list will be the same for all path pairs
2492+ * implementing a given join. clausesel.c will save us from the worst
2493+ * effects of this by caching at the RestrictInfo level; but perhaps it'd
2494+ * be worth finding a way to cache the results at a higher level.
2495+ */
2496+
2497+ /*
2498+ * In an ANTI join, we must ignore clauses that are "pushed down",
2499+ * since those won't affect the match logic. In a SEMI join, we do not
2500+ * distinguish joinquals from "pushed down" quals, so just use the whole
2501+ * restrictinfo list.
2502+ */
2503+ if (jointype == JOIN_ANTI )
2504+ {
2505+ joinquals = NIL ;
2506+ foreach (l ,path -> joinrestrictinfo )
2507+ {
2508+ RestrictInfo * rinfo = (RestrictInfo * )lfirst (l );
2509+
2510+ Assert (IsA (rinfo ,RestrictInfo ));
2511+ if (!rinfo -> is_pushed_down )
2512+ joinquals = lappend (joinquals ,rinfo );
2513+ }
2514+ }
2515+ else
2516+ joinquals = path -> joinrestrictinfo ;
2517+
2518+ /*
2519+ * Get the JOIN_SEMI or JOIN_ANTI selectivity of the join clauses.
2520+ */
2521+ jselec = clauselist_selectivity (root ,
2522+ joinquals ,
2523+ 0 ,
2524+ jointype ,
2525+ sjinfo );
2526+
2527+ /*
2528+ * Also get the normal inner-join selectivity of the join clauses.
2529+ */
2530+ norm_sjinfo .type = T_SpecialJoinInfo ;
2531+ norm_sjinfo .min_lefthand = path -> outerjoinpath -> parent -> relids ;
2532+ norm_sjinfo .min_righthand = path -> innerjoinpath -> parent -> relids ;
2533+ norm_sjinfo .syn_lefthand = path -> outerjoinpath -> parent -> relids ;
2534+ norm_sjinfo .syn_righthand = path -> innerjoinpath -> parent -> relids ;
2535+ norm_sjinfo .jointype = JOIN_INNER ;
2536+ /* we don't bother trying to make the remaining fields valid */
2537+ norm_sjinfo .lhs_strict = false;
2538+ norm_sjinfo .delay_upper_joins = false;
2539+ norm_sjinfo .join_quals = NIL ;
2540+
2541+ nselec = clauselist_selectivity (root ,
2542+ joinquals ,
2543+ 0 ,
2544+ JOIN_INNER ,
2545+ & norm_sjinfo );
2546+
2547+ /* Avoid leaking a lot of ListCells */
2548+ if (jointype == JOIN_ANTI )
2549+ list_free (joinquals );
2550+
2551+ /*
2552+ * jselec can be interpreted as the fraction of outer-rel rows that have
2553+ * any matches (this is true for both SEMI and ANTI cases). And nselec
2554+ * is the fraction of the Cartesian product that matches. So, the
2555+ * average number of matches for each outer-rel row that has at least
2556+ * one match is nselec * inner_rows / jselec.
2557+ *
2558+ * Note: it is correct to use the inner rel's "rows" count here, not
2559+ * PATH_ROWS(), even if the inner path under consideration is an inner
2560+ * indexscan. This is because we have included all the join clauses
2561+ * in the selectivity estimate, even ones used in an inner indexscan.
2562+ */
2563+ if (jselec > 0 )/* protect against zero divide */
2564+ {
2565+ avgmatch = nselec * path -> innerjoinpath -> parent -> rows /jselec ;
2566+ /* Clamp to sane range */
2567+ avgmatch = Max (1.0 ,avgmatch );
2568+ }
2569+ else
2570+ avgmatch = 1.0 ;
2571+
2572+ * outer_match_frac = jselec ;
2573+ * match_count = avgmatch ;
2574+
2575+ /*
2576+ * If requested, check whether the inner path uses all the joinquals
2577+ * as indexquals. (If that's true, we can assume that an unmatched
2578+ * outer tuple is cheap to process, whereas otherwise it's probably
2579+ * expensive.)
2580+ */
2581+ if (indexed_join_quals )
2582+ {
2583+ List * nrclauses ;
2584+
2585+ nrclauses = select_nonredundant_join_clauses (root ,
2586+ path -> joinrestrictinfo ,
2587+ path -> innerjoinpath );
2588+ * indexed_join_quals = (nrclauses == NIL );
2589+ }
2590+
2591+ return true;
2592+ }
2593+
2594+
23232595/*
23242596 * approx_tuple_count
23252597 *Quick-and-dirty estimation of the number of join rows passing