Quick hack to allow the outer query's tuple_fraction to be passed down
to a subquery if the outer query is simple enough that the LIMIT can be reflected directly to the subquery. This didn't use to be very interesting, because a subquery that couldn't have been flattened into the upper query was usually not going to be very responsive to tuple_fraction anyway. But with new code that allows UNION ALL subqueries to pay attention to tuple_fraction, this is useful to do. In particular this lets the optimization occur when the UNION ALL is directly inside a view.
This commit is contained in:
parent
453d74b99c
commit
a87ee007ed
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.133 2005/06/09 04:18:59 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.134 2005/06/10 03:32:21 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -353,6 +353,28 @@ set_inherited_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
set_cheapest(rel);
|
set_cheapest(rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* quick-and-dirty test to see if any joining is needed */
|
||||||
|
static bool
|
||||||
|
has_multiple_baserels(PlannerInfo *root)
|
||||||
|
{
|
||||||
|
int num_base_rels = 0;
|
||||||
|
Index rti;
|
||||||
|
|
||||||
|
for (rti = 1; rti < root->base_rel_array_size; rti++)
|
||||||
|
{
|
||||||
|
RelOptInfo *brel = root->base_rel_array[rti];
|
||||||
|
|
||||||
|
if (brel == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* ignore RTEs that are "other rels" */
|
||||||
|
if (brel->reloptkind == RELOPT_BASEREL)
|
||||||
|
if (++num_base_rels > 1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set_subquery_pathlist
|
* set_subquery_pathlist
|
||||||
* Build the (single) access path for a subquery RTE
|
* Build the (single) access path for a subquery RTE
|
||||||
@ -361,8 +383,10 @@ static void
|
|||||||
set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||||
Index rti, RangeTblEntry *rte)
|
Index rti, RangeTblEntry *rte)
|
||||||
{
|
{
|
||||||
|
Query *parse = root->parse;
|
||||||
Query *subquery = rte->subquery;
|
Query *subquery = rte->subquery;
|
||||||
bool *differentTypes;
|
bool *differentTypes;
|
||||||
|
double tuple_fraction;
|
||||||
List *pathkeys;
|
List *pathkeys;
|
||||||
List *subquery_pathkeys;
|
List *subquery_pathkeys;
|
||||||
|
|
||||||
@ -416,8 +440,24 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
|
|
||||||
pfree(differentTypes);
|
pfree(differentTypes);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can safely pass the outer tuple_fraction down to the subquery
|
||||||
|
* if the outer level has no joining, aggregation, or sorting to do.
|
||||||
|
* Otherwise we'd better tell the subquery to plan for full retrieval.
|
||||||
|
* (XXX This could probably be made more intelligent ...)
|
||||||
|
*/
|
||||||
|
if (parse->hasAggs ||
|
||||||
|
parse->groupClause ||
|
||||||
|
parse->havingQual ||
|
||||||
|
parse->distinctClause ||
|
||||||
|
parse->sortClause ||
|
||||||
|
has_multiple_baserels(root))
|
||||||
|
tuple_fraction = 0.0; /* default case */
|
||||||
|
else
|
||||||
|
tuple_fraction = root->tuple_fraction;
|
||||||
|
|
||||||
/* Generate the plan for the subquery */
|
/* Generate the plan for the subquery */
|
||||||
rel->subplan = subquery_planner(subquery, 0.0 /* default case */,
|
rel->subplan = subquery_planner(subquery, tuple_fraction,
|
||||||
&subquery_pathkeys);
|
&subquery_pathkeys);
|
||||||
|
|
||||||
/* Copy number of output rows from subplan */
|
/* Copy number of output rows from subplan */
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.84 2005/06/08 23:02:04 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.85 2005/06/10 03:32:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -79,6 +79,9 @@ query_planner(PlannerInfo *root, List *tlist, double tuple_fraction,
|
|||||||
Path *cheapestpath;
|
Path *cheapestpath;
|
||||||
Path *sortedpath;
|
Path *sortedpath;
|
||||||
|
|
||||||
|
/* Make tuple_fraction accessible to lower-level routines */
|
||||||
|
root->tuple_fraction = tuple_fraction;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the query has an empty join tree, then it's something easy like
|
* If the query has an empty join tree, then it's something easy like
|
||||||
* "SELECT 2+2;" or "INSERT ... VALUES()". Fall through quickly.
|
* "SELECT 2+2;" or "INSERT ... VALUES()". Fall through quickly.
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.113 2005/06/09 04:19:00 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.114 2005/06/10 03:32:25 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -92,6 +92,8 @@ typedef struct PlannerInfo
|
|||||||
List *query_pathkeys; /* desired pathkeys for query_planner(),
|
List *query_pathkeys; /* desired pathkeys for query_planner(),
|
||||||
* and actual pathkeys afterwards */
|
* and actual pathkeys afterwards */
|
||||||
|
|
||||||
|
double tuple_fraction; /* tuple_fraction passed to query_planner */
|
||||||
|
|
||||||
bool hasJoinRTEs; /* true if any RTEs are RTE_JOIN kind */
|
bool hasJoinRTEs; /* true if any RTEs are RTE_JOIN kind */
|
||||||
bool hasHavingQual; /* true if havingQual was non-null */
|
bool hasHavingQual; /* true if havingQual was non-null */
|
||||||
} PlannerInfo;
|
} PlannerInfo;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user