Commit 05e92dd5 authored by Tom Lane's avatar Tom Lane

Update index cost estimation docs to final 7.0 scheme.

parent 5ac4f32f
<!-- <!--
$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 ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment