<!--
$Header: /usr/prj/pg/cvsroot/doc/doc/src/sgml/indexcost.sgml,v 1.4 2001/05/29 05:24:39 natsuyo Exp $
-->

 <chapter id="indexcost">
  <!-- <title>Index Cost Estimation Functions</title> -->
  <title>インデックスコスト概算関数</title>
<indexterm><primary sortas="いんでっくすこすとがいさんかんすう">インデックスコスト概算関数</primary></indexterm><indexterm><primary sortas="かんすう">関数</primary><secondary sortas="いんでっくすこすとがいさん">インデックスコスト概算</secondary></indexterm><indexterm><primary sortas="いんでっくす">インデックス</primary><secondary sortas="こすとがいさんかんすう">コスト概算関数</secondary></indexterm>
  <note>
   <!-- <title>Author</title> -->
   <title>著者</title>

   <para>
    <!-- Written by Tom Lane (<email>tgl@sss.pgh.pa.us</email>) on 
    2000-01-24-->
    2000年1月24日にTom Lane（<email>tgl@sss.pgh.pa.us</email>）によって書かれました。
   </para>
  </note>

   <note>
    <para>
     <!-- This must eventually become part of a much larger chapter about
     writing new index access methods. -->
     これは最終的には、新しいインデックスアクセスメソッドの書き方についてのもっと大きい章の一部にならなければいけません。
    </para>
   </note>

  <para>
   <!-- Every index access method must provide a cost estimation function for
   use by the planner/optimizer.  The procedure OID of this function is
   given in the <literal>amcostestimate</literal> field of the access
   method's <literal>pg_am</literal> entry. -->

   すべてのインデックスアクセスメソッドは、プランナ/オプティマイザから使用できるようにコスト概算関数を提供しなければいけません。この関数のプロシージャOIDはアクセスメソッドの<literal>pg_am</literal>のフィールド<literal>amcostestimate</literal>で与えられます。
</para>

   <note>
    <para>
     <!-- Prior to Postgres 7.0, a different scheme was used for registering
     index-specific cost estimation functions. -->

     Postgres 7.0以前では、インデックスを指定したコスト概算関数の登録には、違った方法が使われていました。

    </para>
   </note>

  <para>
   <!-- The amcostestimate function is given a list of WHERE clauses that have
   been determined to be usable with the index.  It must return estimates
   of the cost of accessing the index and the selectivity of the WHERE
   clauses (that is, the fraction of main-table tuples that will be
   retrieved during the index scan).  For simple cases, nearly all the
   work of the cost estimator can be done by calling standard routines
   in the optimizer; the point of having an amcostestimate function is
   to allow index access methods to provide index-type-specific knowledge,
   in case it is possible to improve on the standard estimates. -->

   関数amcostestimateは、インデックスと共に使えることが決定されたWHERE句のリストを与えられます。この関数はインデックスにアクセスするコストの概算とWHERE句の選択度（これはインデックススキャンの間に抽出されるメインテーブルのタプルの一部分です）を返さなくてはいけません。単純な場合だと、ほとんどすべてのコスト概算の作業がオプティマイザの標準ルーチンを呼び出すことでできます。amcostestimate関数を持つことの意味は、標準概算を改善することが可能な場合に、インデックスアクセスメソッドがインデックス型を指定した知識を供給することを許可することです。

  </para>

  <para>
   <!-- Each amcostestimate function must have the signature: -->
   それぞれのamcostestimate関数はシグニチャをもたなければいけません。<indexterm><primary>amcostestimate</primary></indexterm><indexterm><primary sortas="かんすう">関数</primary><secondary>amcostestimate</secondary></indexterm>
</para>

<programlisting>
void
amcostestimate (Query *root,
                RelOptInfo *rel,
                IndexOptInfo *index,
                List *indexQuals,
                Cost *indexStartupCost,
                Cost *indexTotalCost,
                Selectivity *indexSelectivity);
</programlisting>

<para>
   <!-- The first four parameters are inputs: -->
   最初の4つのパラメータは引数です。
</para>

   <variablelist>
    <varlistentry>
     <term>root</term>
     <listitem>
      <para>
       <!-- The query being processed. -->
       処理されている問い合わせ。
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term>rel</term>
     <listitem>
      <para>
       <!-- The relation the index is on. -->
       指定されたインデックスがあるリレーション。
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term>index</term>
     <listitem>
      <para>
       <!-- The index itself. -->
        インデックスそのもの。
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term>indexQuals</term>
     <listitem>
      <para>
       <!-- List of index qual clauses (implicitly ANDed);
       a NIL list indicates no qualifiers are available. -->

       インデックス制約句のリスト（暗黙にはANDed）。NILリストは使える制約がないことを表します。<indexterm><primary sortas="いんでっくす">インデックス</primary><secondary sortas="いんでっくすせいやくく">インデックス制約句</secondary></indexterm>

      </para>
     </listitem>
    </varlistentry>
   </variablelist>

  <para>
   <!-- The last three parameters are pass-by-reference outputs: -->
   最後の3つのパラメータは参照渡しの返り値です。
</para>

   <variablelist>
    <varlistentry>
     <term>*indexStartupCost</term>
     <listitem>
      <para>
       <!-- Set to cost of index start-up processing -->
       インデックス開始プロセスのコストに設定されています。<indexterm><primary sortas="いんでっくす">インデックス</primary><secondary sortas="かいしぷろせす">開始プロセス</secondary></indexterm>
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term>*indexTotalCost</term>
     <listitem>
      <para>
       <!-- Set to total cost of index processing -->
       インデックスプロセスの全体のコストに設定されています。<indexterm><primary sortas="いんでっくす">インデックス</primary><secondary sortas="いんでっくすぷろせす">インデックスプロセス</secondary></indexterm>
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term>*indexSelectivity</term>
     <listitem>
      <para>
       <!-- Set to index selectivity -->
        インデックスの選択度に設定されています。<indexterm><primary sortas="いんでっくす">インデックス</primary><secondary sortas="せんたくど">選択度</secondary></indexterm>
      </para>
     </listitem>
    </varlistentry>
   </variablelist>

  <para>
   <!-- Note that cost estimate functions must be written in C, not in SQL or
   any available procedural language, because they must access internal
   data structures of the planner/optimizer. -->
   コスト概算関数は、SQLやその他の手続言語ではなく、C言語で書かれなければいけないことに注意してください。これはプランナ/オプティマイザの内部データ構造にアクセスしなければいけないためです。

  </para>

  <para>
   <!-- The index access costs should be computed in the units used by
   src/backend/optimizer/path/costsize.c: a sequential disk block fetch
   has cost 1.0, a nonsequential fetch has cost random_page_cost, and
   the cost of processing one index tuple should usually be taken as
   cpu_index_tuple_cost (which is a user-adjustable optimizer parameter).
   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). -->

   インデックスアクセスコストはsrc/backend/optimizer/path/costsize.cで使われるユニットで計算されるべきです。順番に並んだディスクブロック取り出しは1.0のコストがかかっており、順不同の取り出しはrandom_page_costのコストがかかっています。そして、1つのインデックスタプルの処理のコストは通常cpu_index_tuple_costとされるべきです（これはユーザーが調節可能なオプティマイザパラメータです）。さらに、cpu_operator_costが相応の数に増えると、インデックス処理の間に呼び出される比較演算子もコストに加算されます（特にindexQuals自身の評価では）。
  </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. -->

   アクセスコストは、インデックス自身のスキャンと関係するすべてのディスクとCPUコストも含むべきですが、インデックスで指定されるメインテーブルのタプルの処理や抽出は含みません。

  </para>

  <para>
   <!-- The "start-up 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 start-up cost might want
   to set it nonzero. -->

   「開始コスト」は、最初のタプルの取り出しを始める前に使い果たされなければならない総計スキャンコストの一部です。ほとんどのインデックスではこれは0とされますが、高い開始コストを持つインデックス型では0以外に設定した方がよいかもしれません。
  </para>

  <para>
   <!-- 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
   of a lossy index, this will typically be higher than the fraction of
   tuples that actually pass the given qual conditions. -->

   indexSelectivityは、インデックススキャンの間に抽出されるメインテーブルのタプルの概算された一部分として設定されるべきです。浪費の多いインデックスの場合はこの値が、与えられた制約条件を実際に通過するタプルの部分よりも高くなることがよくあります。

  </para>

  <procedure>
   <!-- <title>Cost Estimation</title> -->
   <title>コスト概算</title>
   <para>
    <!-- A typical cost estimator will proceed as follows: -->
    典型的なコスト概算は次のように進められます。
   </para>
<indexterm><primary sortas="いんでっくす">インデックス</primary><secondary sortas="こすとがいさん">コスト概算</secondary></indexterm>
   <step>
    <para>
     <!-- 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
     knowledge, use the standard optimizer function clauselist_selectivity(): 
     -->

     与えられた制約条件に基づいて訪れられるメインテーブルのタプルの一部分を概算して返します。インデックス型を指定した知識がない場合、標準のオプティマイザ関数であるclauselist_selectivity()を使ってください。<indexterm><primary>clauselist_selectivity()</primary></indexterm><indexterm><primary sortas="かんすう">関数</primary><secondary>clauselist_selectivity()</secondary></indexterm>
</para>


<programlisting>
*indexSelectivity = clauselist_selectivity(root, indexQuals,
                                           lfirsti(rel->relids));
</programlisting>
   </step>

   <step>
    <para>
     <!-- Estimate the number of index tuples that will be visited during the
     scan.  For many index types this is the same as indexSelectivity times
     the number of tuples in the index, but it might be more.  (Note that the
     index's size in pages and tuples is available from the IndexOptInfo 
     struct.) -->

     スキャン中に訪れられるインデックスタプルの数を概算します。多くのインデックス型にとって、これはindexSelectivityとインデックスの中にあるタプルの数を掛けたものと等しいですが、それより多い場合もあります（インデックスのページ数とタプルはIndexOptInfo構文から得ることができます）。

    </para>
   </step>

   <step>
    <para>
     <!-- Estimate the number of index pages that will be retrieved during 
     the scan.
     This might be just indexSelectivity times the index's size in pages.-->

     スキャン中に抽出されるインデックスページの数を概算します。これはindexSelectivityとインデックスのページ数ちょうどでしょう。
    </para>
   </step>

   <step>
    <para>
     <!-- Compute the index access cost.  A generic estimator might do this:
     -->
      インデックスアクセスコストを計算します。一般的な概算では以下ようなことをするでしょう。
</para>

<programlisting>
<!--    /*
     * 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;-->    /* ここでの全体的な憶測は、インデックスページが順番に読まれ、それぞれに
     * random_page_cost ではなく 1.0 のコストがかかるということです。
     * さらに、それぞれのインデックスタプルの indexquals の評価も加算され
     * ます。すべてのコストはスキャンの間増加しながらかかっていくと
     * 仮定されます。
     */

    *indexStartupCost = 0;
    *indexTotalCost = numIndexPages +
        (cpu_index_tuple_cost + cost_qual_eval(indexQuals)) * numIndexTuples;
</programlisting>
   </step>
  </procedure>

  <para>
   <!-- Examples of cost estimator functions can be found in
   <filename>src/backend/utils/adt/selfuncs.c</filename>. -->
   コスト概算関数の例は、<filename>src/backend/utils/adt/selfuncs.c</filename>で見つけることができます。

  </para>

  <para>
   <!-- By convention, the <literal>pg_proc</literal> entry for an
   <literal>amcostestimate</literal> function should show -->
   通常は、<literal>amcostestimate</literal>関数の<literal>pg_proc</literal>項目は下記のように表示されます。
</para>

<programlisting>
prorettype = 0
pronargs = 7
proargtypes = 0 0 0 0 0 0 0
</programlisting>

<para>
   <!-- We use zero ("opaque") for all the arguments since none of them have 
   types
   that are known in pg_type. -->
   pg_typeで知られる型を持っている引数がないため、ここでは0（ゼロ）を使っています。

  </para>
 </chapter>

<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"./reference.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:("/usr/lib/sgml/catalog")
sgml-local-ecat-files:nil
End:
-->
