mirror of
https://github.com/postgres/postgres.git
synced 2025-07-18 17:42:25 +03:00
Teach the planner to treat a partial unique index as proving a variable is
unique for a particular query, if the index predicate is satisfied. This requires a bit of reordering of operations so that we check the predicates before doing any selectivity estimates, but shouldn't really cause any noticeable slowdown. Per a comment from Michal Politowski.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.179 2009/01/01 17:23:43 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.180 2009/02/15 20:16:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -225,19 +225,25 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test any partial indexes of rel for applicability. We must do this
|
||||
* first since partial unique indexes can affect size estimates.
|
||||
*/
|
||||
check_partial_indexes(root, rel);
|
||||
|
||||
/* Mark rel with estimated output rows, width, etc */
|
||||
set_baserel_size_estimates(root, rel);
|
||||
|
||||
/* Test any partial indexes of rel for applicability */
|
||||
check_partial_indexes(root, rel);
|
||||
|
||||
/*
|
||||
* Check to see if we can extract any restriction conditions from join
|
||||
* quals that are OR-of-AND structures. If so, add them to the rel's
|
||||
* restriction list, and recompute the size estimates.
|
||||
* restriction list, and redo the above steps.
|
||||
*/
|
||||
if (create_or_index_quals(root, rel))
|
||||
{
|
||||
check_partial_indexes(root, rel);
|
||||
set_baserel_size_estimates(root, rel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate paths and add them to the rel's pathlist.
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.235 2009/01/01 17:23:43 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.236 2009/02/15 20:16:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1367,8 +1367,12 @@ match_rowcompare_to_indexcol(IndexOptInfo *index,
|
||||
|
||||
/*
|
||||
* check_partial_indexes
|
||||
* Check each partial index of the relation, and mark it predOK or not
|
||||
* depending on whether the predicate is satisfied for this query.
|
||||
* Check each partial index of the relation, and mark it predOK if
|
||||
* the index's predicate is satisfied for this query.
|
||||
*
|
||||
* Note: it is possible for this to get re-run after adding more restrictions
|
||||
* to the rel; so we might be able to prove more indexes OK. We assume that
|
||||
* adding more restrictions can't make an index not OK.
|
||||
*/
|
||||
void
|
||||
check_partial_indexes(PlannerInfo *root, RelOptInfo *rel)
|
||||
@ -1383,6 +1387,9 @@ check_partial_indexes(PlannerInfo *root, RelOptInfo *rel)
|
||||
if (index->indpred == NIL)
|
||||
continue; /* ignore non-partial indexes */
|
||||
|
||||
if (index->predOK)
|
||||
continue; /* don't repeat work if already proven OK */
|
||||
|
||||
index->predOK = predicate_implied_by(index->indpred,
|
||||
restrictinfo_list);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.87 2009/02/06 23:43:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.88 2009/02/15 20:16:21 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -181,6 +181,6 @@ create_or_index_quals(PlannerInfo *root, RelOptInfo *rel)
|
||||
/* It isn't an outer join clause, so no need to adjust outer_selec */
|
||||
}
|
||||
|
||||
/* Tell caller to recompute rel's rows estimate */
|
||||
/* Tell caller to recompute partial index status and rowcount estimate */
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user