mirror of
https://github.com/postgres/postgres.git
synced 2025-07-09 22:41:56 +03:00
Fix cost_nestloop and cost_hashjoin to model the behavior of semi and anti
joins a bit better, ie, understand the differing cost functions for matched and unmatched outer tuples. There is more that could be done in cost_hashjoin but this already helps a great deal. Per discussions with Robert Haas.
This commit is contained in:
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.258 2009/04/19 19:46:33 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.259 2009/05/09 22:51:41 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1562,62 +1562,16 @@ create_nestloop_plan(PlannerInfo *root,
|
||||
List *otherclauses;
|
||||
NestLoop *join_plan;
|
||||
|
||||
if (IsA(best_path->innerjoinpath, IndexPath))
|
||||
{
|
||||
/*
|
||||
* An index is being used to reduce the number of tuples scanned in
|
||||
* the inner relation. If there are join clauses being used with the
|
||||
* index, we may remove those join clauses from the list of clauses
|
||||
* that have to be checked as qpquals at the join node.
|
||||
*
|
||||
* We can also remove any join clauses that are redundant with those
|
||||
* being used in the index scan; this check is needed because
|
||||
* find_eclass_clauses_for_index_join() may emit different clauses
|
||||
* than generate_join_implied_equalities() did.
|
||||
*
|
||||
* We can skip this if the index path is an ordinary indexpath and not
|
||||
* a special innerjoin path, since it then wouldn't be using any join
|
||||
* clauses.
|
||||
*/
|
||||
IndexPath *innerpath = (IndexPath *) best_path->innerjoinpath;
|
||||
|
||||
if (innerpath->isjoininner)
|
||||
joinrestrictclauses =
|
||||
select_nonredundant_join_clauses(root,
|
||||
joinrestrictclauses,
|
||||
innerpath->indexclauses);
|
||||
}
|
||||
else if (IsA(best_path->innerjoinpath, BitmapHeapPath))
|
||||
{
|
||||
/*
|
||||
* Same deal for bitmapped index scans.
|
||||
*
|
||||
* Note: both here and above, we ignore any implicit index
|
||||
* restrictions associated with the use of partial indexes. This is
|
||||
* OK because we're only trying to prove we can dispense with some
|
||||
* join quals; failing to prove that doesn't result in an incorrect
|
||||
* plan. It is the right way to proceed because adding more quals to
|
||||
* the stuff we got from the original query would just make it harder
|
||||
* to detect duplication. (Also, to change this we'd have to be wary
|
||||
* of UPDATE/DELETE/SELECT FOR UPDATE target relations; see notes
|
||||
* above about EvalPlanQual.)
|
||||
*/
|
||||
BitmapHeapPath *innerpath = (BitmapHeapPath *) best_path->innerjoinpath;
|
||||
|
||||
if (innerpath->isjoininner)
|
||||
{
|
||||
List *bitmapclauses;
|
||||
|
||||
bitmapclauses =
|
||||
make_restrictinfo_from_bitmapqual(innerpath->bitmapqual,
|
||||
true,
|
||||
false);
|
||||
joinrestrictclauses =
|
||||
select_nonredundant_join_clauses(root,
|
||||
joinrestrictclauses,
|
||||
bitmapclauses);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If the inner path is a nestloop inner indexscan, it might be using
|
||||
* some of the join quals as index quals, in which case we don't have
|
||||
* to check them again at the join node. Remove any join quals that
|
||||
* are redundant.
|
||||
*/
|
||||
joinrestrictclauses =
|
||||
select_nonredundant_join_clauses(root,
|
||||
joinrestrictclauses,
|
||||
best_path->innerjoinpath);
|
||||
|
||||
/* Sort join qual clauses into best execution order */
|
||||
joinrestrictclauses = order_qual_clauses(root, joinrestrictclauses);
|
||||
|
Reference in New Issue
Block a user