aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/plancat.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-01-22 23:50:30 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-01-22 23:50:30 +0000
commit71ed7eb4941ddb32700a51a8b8b3403eceeca4a9 (patch)
treee2452e2e308d6066c2c7e255eab5332cfcb4baa8 /src/backend/optimizer/util/plancat.c
parent78845177bb8839a2a582b92de2b46ce7d3f16df4 (diff)
downloadpostgresql-71ed7eb4941ddb32700a51a8b8b3403eceeca4a9.tar.gz
postgresql-71ed7eb4941ddb32700a51a8b8b3403eceeca4a9.zip
Revise handling of index-type-specific indexscan cost estimation, per
pghackers discussion of 5-Jan-2000. The amopselect and amopnpages estimators are gone, and in their place is a per-AM amcostestimate procedure (linked to from pg_am, not pg_amop).
Diffstat (limited to 'src/backend/optimizer/util/plancat.c')
-rw-r--r--src/backend/optimizer/util/plancat.c213
1 files changed, 2 insertions, 211 deletions
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 6468ef528fd..4c191f02b55 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.44 2000/01/15 02:59:31 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.45 2000/01/22 23:50:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -136,6 +136,7 @@ find_secondary_indexes(Query *root, Index relid)
info->relam = relam;
info->pages = indexRelation->rd_rel->relpages;
info->tuples = indexRelation->rd_rel->reltuples;
+ info->amcostestimate = index_cost_estimator(indexRelation);
index_close(indexRelation);
/*
@@ -169,216 +170,6 @@ find_secondary_indexes(Query *root, Index relid)
}
/*
- * index_selectivity
- * Estimate the selectivity of an index scan with the given index quals.
- *
- * NOTE: an indexscan plan node can actually represent several passes,
- * but here we consider the cost of just one pass.
- *
- * 'root' is the query root
- * 'rel' is the relation being scanned
- * 'index' is the index to be used
- * 'indexquals' is the list of qual condition exprs (implicit AND semantics)
- * '*idxPages' receives an estimate of the number of index pages touched
- * '*idxSelec' receives an estimate of selectivity of the scan, ie fraction
- * of the relation's tuples that will be retrieved
- */
-void
-index_selectivity(Query *root,
- RelOptInfo *rel,
- IndexOptInfo *index,
- List *indexquals,
- long *idxPages,
- Selectivity *idxSelec)
-{
- int relid;
- Oid baserelid,
- indexrelid;
- HeapTuple indRel,
- indexTuple;
- Form_pg_class indexrelation;
- Oid relam;
- Form_pg_index pgindex;
- int nIndexKeys;
- float64data npages,
- select,
- fattr_select;
- bool nphack = false;
- List *q;
-
- Assert(length(rel->relids) == 1); /* must be a base rel */
- relid = lfirsti(rel->relids);
-
- baserelid = getrelid(relid, root->rtable);
- indexrelid = index->indexoid;
-
- indRel = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(indexrelid),
- 0, 0, 0);
- if (!HeapTupleIsValid(indRel))
- elog(ERROR, "index_selectivity: index %u not found in pg_class",
- indexrelid);
- indexrelation = (Form_pg_class) GETSTRUCT(indRel);
- relam = indexrelation->relam;
-
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexrelid),
- 0, 0, 0);
- if (!HeapTupleIsValid(indexTuple))
- elog(ERROR, "index_selectivity: index %u not found in pg_index",
- indexrelid);
- pgindex = (Form_pg_index) GETSTRUCT(indexTuple);
-
- nIndexKeys = 1;
- while (pgindex->indclass[nIndexKeys] != InvalidOid)
- nIndexKeys++;
-
- /*
- * Hack for non-functional btree npages estimation: npages =
- * index_pages * selectivity_of_1st_attr_clause(s) - vadim 04/24/97
- */
- if (relam == BTREE_AM_OID && pgindex->indproc == InvalidOid)
- nphack = true;
-
- npages = 0.0;
- select = 1.0;
- fattr_select = 1.0;
-
- foreach(q, indexquals)
- {
- Node *expr = (Node *) lfirst(q);
- Oid opno;
- int dummyrelid;
- AttrNumber attno;
- Datum value;
- int flag;
- Oid indclass;
- HeapTuple amopTuple;
- Form_pg_amop amop;
- float64 amopnpages,
- amopselect;
-
- /*
- * Extract info from clause.
- */
- if (is_opclause(expr))
- opno = ((Oper *) ((Expr *) expr)->oper)->opno;
- else
- opno = InvalidOid;
- get_relattval(expr, relid, &dummyrelid, &attno, &value, &flag);
-
- /*
- * Find the AM class for this key.
- */
- if (pgindex->indproc != InvalidOid)
- {
- /*
- * Functional index: AM class is the first one defined since
- * functional indices have exactly one key.
- */
- indclass = pgindex->indclass[0];
- }
- else
- {
- int i;
- indclass = InvalidOid;
- for (i = 0; pgindex->indkey[i]; i++)
- {
- if (attno == pgindex->indkey[i])
- {
- indclass = pgindex->indclass[i];
- break;
- }
- }
- }
- if (!OidIsValid(indclass))
- {
- /*
- * Presumably this means that we are using a functional index
- * clause and so had no variable to match to the index key ...
- * if not we are in trouble.
- */
- elog(NOTICE, "index_selectivity: no key %d in index %u",
- attno, indexrelid);
- continue;
- }
-
- amopTuple = SearchSysCacheTuple(AMOPOPID,
- ObjectIdGetDatum(indclass),
- ObjectIdGetDatum(opno),
- ObjectIdGetDatum(relam),
- 0);
- if (!HeapTupleIsValid(amopTuple))
- {
- /*
- * We might get here because indxpath.c selected a binary-
- * compatible index. Try again with the compatible operator.
- */
- if (opno != InvalidOid)
- {
- opno = indexable_operator((Expr *) expr, indclass, relam,
- ((flag & SEL_RIGHT) != 0));
- amopTuple = SearchSysCacheTuple(AMOPOPID,
- ObjectIdGetDatum(indclass),
- ObjectIdGetDatum(opno),
- ObjectIdGetDatum(relam),
- 0);
- }
- if (!HeapTupleIsValid(amopTuple))
- elog(ERROR, "index_selectivity: no amop %u %u %u",
- indclass, opno, relam);
- }
- amop = (Form_pg_amop) GETSTRUCT(amopTuple);
-
- if (!nphack)
- {
- amopnpages = (float64) fmgr(amop->amopnpages,
- (char *) opno,
- (char *) baserelid,
- (char *) (int) attno,
- (char *) value,
- (char *) flag,
- (char *) nIndexKeys,
- (char *) indexrelid);
- if (PointerIsValid(amopnpages))
- npages += *amopnpages;
- }
-
- amopselect = (float64) fmgr(amop->amopselect,
- (char *) opno,
- (char *) baserelid,
- (char *) (int) attno,
- (char *) value,
- (char *) flag,
- (char *) nIndexKeys,
- (char *) indexrelid);
- if (PointerIsValid(amopselect))
- {
- select *= *amopselect;
- if (nphack && attno == pgindex->indkey[0])
- fattr_select *= *amopselect;
- }
- }
-
- /*
- * Estimation of npages below is hack of course, but it's better than
- * it was before. - vadim 04/09/97
- */
- if (nphack)
- {
- npages = fattr_select * indexrelation->relpages;
- *idxPages = (long) ceil((double) npages);
- }
- else
- {
- if (nIndexKeys > 1)
- npages = npages / (1.0 + nIndexKeys);
- *idxPages = (long) ceil((double) (npages / nIndexKeys));
- }
- *idxSelec = select;
-}
-
-/*
* restriction_selectivity
*
* Returns the selectivity of a specified operator.