diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-01-27 19:26:38 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-01-27 19:26:38 -0500 |
commit | e2fa76d80ba571d4de8992de6386536867250474 (patch) | |
tree | f2101a671cde7cf9859cc7c37b08e5daf50b428e /src/backend/utils/adt/selfuncs.c | |
parent | b376ec6fa57bc76037014ede29498e2d1611968e (diff) | |
download | postgresql-e2fa76d80ba571d4de8992de6386536867250474.tar.gz postgresql-e2fa76d80ba571d4de8992de6386536867250474.zip |
Use parameterized paths to generate inner indexscans more flexibly.
This patch fixes the planner so that it can generate nestloop-with-
inner-indexscan plans even with one or more levels of joining between
the indexscan and the nestloop join that is supplying the parameter.
The executor was fixed to handle such cases some time ago, but the
planner was not ready. This should improve our plans in many situations
where join ordering restrictions formerly forced complete table scans.
There is probably a fair amount of tuning work yet to be done, because
of various heuristics that have been added to limit the number of
parameterized paths considered. However, we are not going to find out
what needs to be adjusted until the code gets some real-world use, so
it's time to get it in there where it can be tested easily.
Note API change for index AM amcostestimate functions. I'm not aware of
any non-core index AMs, but if there are any, they will need minor
adjustments.
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 37 |
1 files changed, 13 insertions, 24 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index da638f885aa..09c92404902 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -5971,7 +5971,7 @@ string_to_bytea_const(const char *str, size_t str_len) static void genericcostestimate(PlannerInfo *root, IndexPath *path, - RelOptInfo *outer_rel, + double loop_count, double numIndexTuples, Cost *indexStartupCost, Cost *indexTotalCost, @@ -6119,16 +6119,8 @@ genericcostestimate(PlannerInfo *root, * Note that we are counting pages not tuples anymore, so we take N = T = * index size, as if there were one "tuple" per page. */ - if (outer_rel != NULL && outer_rel->rows > 1) - { - num_outer_scans = outer_rel->rows; - num_scans = num_sa_scans * num_outer_scans; - } - else - { - num_outer_scans = 1; - num_scans = num_sa_scans; - } + num_outer_scans = loop_count; + num_scans = num_sa_scans * num_outer_scans; if (num_scans > 1) { @@ -6234,7 +6226,7 @@ btcostestimate(PG_FUNCTION_ARGS) { PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - RelOptInfo *outer_rel = (RelOptInfo *) PG_GETARG_POINTER(2); + double loop_count = PG_GETARG_FLOAT8(2); Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); @@ -6410,7 +6402,7 @@ btcostestimate(PG_FUNCTION_ARGS) numIndexTuples = rint(numIndexTuples / num_sa_scans); } - genericcostestimate(root, path, outer_rel, + genericcostestimate(root, path, loop_count, numIndexTuples, indexStartupCost, indexTotalCost, indexSelectivity, indexCorrelation); @@ -6527,13 +6519,13 @@ hashcostestimate(PG_FUNCTION_ARGS) { PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - RelOptInfo *outer_rel = (RelOptInfo *) PG_GETARG_POINTER(2); + double loop_count = PG_GETARG_FLOAT8(2); Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); double *indexCorrelation = (double *) PG_GETARG_POINTER(6); - genericcostestimate(root, path, outer_rel, 0.0, + genericcostestimate(root, path, loop_count, 0.0, indexStartupCost, indexTotalCost, indexSelectivity, indexCorrelation); @@ -6545,13 +6537,13 @@ gistcostestimate(PG_FUNCTION_ARGS) { PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - RelOptInfo *outer_rel = (RelOptInfo *) PG_GETARG_POINTER(2); + double loop_count = PG_GETARG_FLOAT8(2); Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); double *indexCorrelation = (double *) PG_GETARG_POINTER(6); - genericcostestimate(root, path, outer_rel, 0.0, + genericcostestimate(root, path, loop_count, 0.0, indexStartupCost, indexTotalCost, indexSelectivity, indexCorrelation); @@ -6563,13 +6555,13 @@ spgcostestimate(PG_FUNCTION_ARGS) { PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - RelOptInfo *outer_rel = (RelOptInfo *) PG_GETARG_POINTER(2); + double loop_count = PG_GETARG_FLOAT8(2); Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); double *indexCorrelation = (double *) PG_GETARG_POINTER(6); - genericcostestimate(root, path, outer_rel, 0.0, + genericcostestimate(root, path, loop_count, 0.0, indexStartupCost, indexTotalCost, indexSelectivity, indexCorrelation); @@ -6884,7 +6876,7 @@ gincostestimate(PG_FUNCTION_ARGS) { PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); IndexPath *path = (IndexPath *) PG_GETARG_POINTER(1); - RelOptInfo *outer_rel = (RelOptInfo *) PG_GETARG_POINTER(2); + double loop_count = PG_GETARG_FLOAT8(2); Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3); Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4); Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5); @@ -7051,10 +7043,7 @@ gincostestimate(PG_FUNCTION_ARGS) } /* Will we have more than one iteration of a nestloop scan? */ - if (outer_rel != NULL && outer_rel->rows > 1) - outer_scans = outer_rel->rows; - else - outer_scans = 1; + outer_scans = loop_count; /* * Compute cost to begin scan, first of all, pay attention to pending list. |