diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-01-22 23:50:30 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-01-22 23:50:30 +0000 |
commit | 71ed7eb4941ddb32700a51a8b8b3403eceeca4a9 (patch) | |
tree | e2452e2e308d6066c2c7e255eab5332cfcb4baa8 /src/backend/optimizer/util/plancat.c | |
parent | 78845177bb8839a2a582b92de2b46ce7d3f16df4 (diff) | |
download | postgresql-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.c | 213 |
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. |