mirror of
https://github.com/postgres/postgres.git
synced 2025-06-10 09:21:54 +03:00
Update index cost estimation docs to final 7.0 scheme.
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/indexcost.sgml,v 2.2 2000/03/31 03:27:40 thomas Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/indexcost.sgml,v 2.3 2000/03/31 17:18:26 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter>
|
<chapter>
|
||||||
@ -14,20 +14,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/indexcost.sgml,v 2.2 2000/03/31 03:27
|
|||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<!--
|
<note>
|
||||||
I have written the attached bit of doco about the new index cost
|
<para>
|
||||||
estimator procedure definition, but I am not sure where to put it.
|
This must eventually become part of a much larger chapter about
|
||||||
There isn't (AFAICT) any existing documentation about how to make
|
writing new index access methods.
|
||||||
a new kind of index, which would be the proper place for it.
|
</para>
|
||||||
May I impose on you to find/make a place for this and mark it up
|
</note>
|
||||||
properly?
|
|
||||||
|
|
||||||
Also, doc/src/graphics/catalogs.ag needs to be updated, but I have
|
|
||||||
no idea how. (The amopselect and amopnpages fields of pg_amop
|
|
||||||
are gone; pg_am has a new field amcostestimate.)
|
|
||||||
|
|
||||||
regards, tom lane
|
|
||||||
-->
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Every index access method must provide a cost estimation function for
|
Every index access method must provide a cost estimation function for
|
||||||
@ -64,7 +56,8 @@ amcostestimate (Query *root,
|
|||||||
RelOptInfo *rel,
|
RelOptInfo *rel,
|
||||||
IndexOptInfo *index,
|
IndexOptInfo *index,
|
||||||
List *indexQuals,
|
List *indexQuals,
|
||||||
Cost *indexAccessCost,
|
Cost *indexStartupCost,
|
||||||
|
Cost *indexTotalCost,
|
||||||
Selectivity *indexSelectivity);
|
Selectivity *indexSelectivity);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
@ -111,14 +104,23 @@ amcostestimate (Query *root,
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The last two parameters are pass-by-reference outputs:
|
The last three parameters are pass-by-reference outputs:
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>*indexAccessCost</term>
|
<term>*indexStartupCost</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Set to cost of index processing.
|
Set to cost of index startup processing
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>*indexTotalCost</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Set to total cost of index processing
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -141,15 +143,29 @@ amcostestimate (Query *root,
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The indexAccessCost should be computed in the units used by
|
The index access costs should be computed in the units used by
|
||||||
src/backend/optimizer/path/costsize.c: a disk block fetch has cost 1.0,
|
src/backend/optimizer/path/costsize.c: a sequential disk block fetch
|
||||||
and the cost of processing one index tuple should usually be taken as
|
has cost 1.0, a nonsequential fetch has cost random_page_cost, and
|
||||||
cpu_index_page_weight (which is a user-adjustable optimizer parameter).
|
the cost of processing one index tuple should usually be taken as
|
||||||
The access cost should include all disk and CPU costs associated with
|
cpu_index_tuple_cost (which is a user-adjustable optimizer parameter).
|
||||||
scanning the index itself, but NOT the cost of retrieving or processing
|
In addition, an appropriate multiple of cpu_operator_cost should be charged
|
||||||
|
for any comparison operators invoked during index processing (especially
|
||||||
|
evaluation of the indexQuals themselves).
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The access costs should include all disk and CPU costs associated with
|
||||||
|
scanning the index itself, but NOT the costs of retrieving or processing
|
||||||
the main-table tuples that are identified by the index.
|
the main-table tuples that are identified by the index.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The "startup cost" is the part of the total scan cost that must be expended
|
||||||
|
before we can begin to fetch the first tuple. For most indexes this can
|
||||||
|
be taken as zero, but an index type with a high startup cost might want
|
||||||
|
to set it nonzero.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The indexSelectivity should be set to the estimated fraction of the main
|
The indexSelectivity should be set to the estimated fraction of the main
|
||||||
table tuples that will be retrieved during the index scan. In the case
|
table tuples that will be retrieved during the index scan. In the case
|
||||||
@ -167,10 +183,11 @@ amcostestimate (Query *root,
|
|||||||
<para>
|
<para>
|
||||||
Estimate and return the fraction of main-table tuples that will be visited
|
Estimate and return the fraction of main-table tuples that will be visited
|
||||||
based on the given qual conditions. In the absence of any index-type-specific
|
based on the given qual conditions. In the absence of any index-type-specific
|
||||||
knowledge, use the standard optimizer function clauselist_selec():
|
knowledge, use the standard optimizer function clauselist_selectivity():
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
*indexSelectivity = clauselist_selec(root, indexQuals);
|
*indexSelectivity = clauselist_selectivity(root, indexQuals,
|
||||||
|
lfirsti(rel->relids));
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</step>
|
</step>
|
||||||
@ -193,10 +210,18 @@ amcostestimate (Query *root,
|
|||||||
|
|
||||||
<step>
|
<step>
|
||||||
<para>
|
<para>
|
||||||
Compute the index access cost as
|
Compute the index access cost. A generic estimator might do this:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
*indexAccessCost = numIndexPages + cpu_index_page_weight * numIndexTuples;
|
/*
|
||||||
|
* Our generic assumption is that the index pages will be read
|
||||||
|
* sequentially, so they have cost 1.0 each, not random_page_cost.
|
||||||
|
* Also, we charge for evaluation of the indexquals at each index tuple.
|
||||||
|
* All the costs are assumed to be paid incrementally during the scan.
|
||||||
|
*/
|
||||||
|
*indexStartupCost = 0;
|
||||||
|
*indexTotalCost = numIndexPages +
|
||||||
|
(cpu_index_tuple_cost + cost_qual_eval(indexQuals)) * numIndexTuples;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</step>
|
</step>
|
||||||
@ -213,8 +238,8 @@ amcostestimate (Query *root,
|
|||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
prorettype = 0
|
prorettype = 0
|
||||||
pronargs = 6
|
pronargs = 7
|
||||||
proargtypes = 0 0 0 0 0 0
|
proargtypes = 0 0 0 0 0 0 0
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
We use zero ("opaque") for all the arguments since none of them have types
|
We use zero ("opaque") for all the arguments since none of them have types
|
||||||
|
Reference in New Issue
Block a user