Fix choose_bitmap_and() so that partial index predicates are considered when
deciding whether a potential additional indexscan is redundant or not. As now coded, any use of a partial index that was already used in a previous AND arm will be rejected as redundant. This might be overly restrictive, but not considering the point at all is definitely bad, as per example in bug #2441 from Arjen van der Meijden. In particular, a clauseless scan of a partial index was *never* considered redundant by the previous coding, and that's surely wrong. Being more flexible would also require some consideration of how not to double-count the index predicate's selectivity.
This commit is contained in:
parent
f323252642
commit
eed57b1b92
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.205 2006/05/18 17:12:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.206 2006/05/18 19:56:46 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -616,10 +616,10 @@ choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, List *paths)
|
||||
* non-selective. In any case, we'd surely be drastically misestimating
|
||||
* the selectivity if we count the same condition twice.
|
||||
*
|
||||
* XXX is there any risk of throwing away a useful partial index here
|
||||
* because we don't explicitly look at indpred? At least in simple cases,
|
||||
* the partial index will sort before competing non-partial indexes and so
|
||||
* it makes the right choice, but perhaps we need to work harder.
|
||||
* We include index predicate conditions in the redundancy test. Because
|
||||
* the test is just for pointer equality and not equal(), the effect is
|
||||
* that use of the same partial index in two different AND elements is
|
||||
* considered redundant. (XXX is this too strong?)
|
||||
*
|
||||
* Note: outputting the selected sub-paths in selectivity order is a good
|
||||
* thing even if we weren't using that as part of the selection method,
|
||||
@ -732,14 +732,14 @@ bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel, List *paths)
|
||||
/*
|
||||
* pull_indexpath_quals
|
||||
*
|
||||
* Given the Path structure for a plain or bitmap indexscan, extract a
|
||||
* list of RestrictInfo nodes for all the indexquals used in the Path.
|
||||
* Given the Path structure for a plain or bitmap indexscan, extract a list
|
||||
* of all the indexquals and index predicate conditions used in the Path.
|
||||
*
|
||||
* This is sort of a simplified version of make_restrictinfo_from_bitmapqual;
|
||||
* here, we are not trying to produce an accurate representation of the AND/OR
|
||||
* semantics of the Path, but just find out all the base conditions used.
|
||||
*
|
||||
* The result list contains pointers to the RestrictInfos used in the Path,
|
||||
* The result list contains pointers to the expressions used in the Path,
|
||||
* but all the list cells are freshly built, so it's safe to destructively
|
||||
* modify the list (eg, by concat'ing it with other lists).
|
||||
*/
|
||||
@ -777,7 +777,8 @@ pull_indexpath_quals(Path *bitmapqual)
|
||||
{
|
||||
IndexPath *ipath = (IndexPath *) bitmapqual;
|
||||
|
||||
result = list_copy(ipath->indexclauses);
|
||||
result = get_actual_clauses(ipath->indexclauses);
|
||||
result = list_concat(result, list_copy(ipath->indexinfo->indpred));
|
||||
}
|
||||
else
|
||||
elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual));
|
||||
|
Loading…
x
Reference in New Issue
Block a user