<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<!-- EN-Revision: 24249 -->
<sect1 id="performance.database">
    <title>Zend_Dbパフォーマンス</title>

    <para>
        <classname>Zend_Db</classname>はデータベースを抽象化するレイヤーで、
        <acronym>SQL</acronym>操作のための共通<acronym>API</acronym>を提供する意図があります。
        <classname>Zend_Db_Table</classname>はテーブルデータのゲートウェイで、
        テーブルレベルでの抽象的な共通のデータベース操作を提供する意図があります。
        それらの抽象的な性質とそれらの操作を行なうために隠れて行なうマジックのせいで、
        しばしばパフォーマンスのオーバーヘッドをもたらします。
    </para>

    <sect2 id="performance.database.tableMetadata">
        <title>テーブルのメタデータを取得する際にZend_Db_Tableによってもたらされる
        オーバーヘッドをどのようにしたら減らせますか？</title>

        <para>
            できる限り使い方を簡単に保つために、
            また、開発最中にスキーマの変更を絶えずサポートするためにも、
            <classname>Zend_Db_Table</classname>はあるマジックを隠れて行ないます:
            使い始める時にテーブルのスキーマを読み込んでオブジェクトのメンバに保存します。
            この操作は一般的に高くつき、データベースを気にかけません。
            それは製品のボトルネックに寄与します。
        </para>

        <para>
            幸運なことにその状況を改善する技術があります。
        </para>

        <sect3 id="performance.database.tableMetadata.cache">
            <title>メタデータキャッシュの利用</title>

            <para>
                <classname>Zend_Db_Table</classname>ではテーブルのメタデータをキャッシュする
                ために<classname>Zend_Cache</classname>を任意で利用できます。
                これはデータベース自身からメタデータを読み込むよりも、
                一般的に早くアクセスでき、高くつきません。
            </para>

            <para>
                <link linkend="zend.db.table.metadata.caching"><classname>Zend_Db_Table</classname>
                のドキュメントにメタデータをキャッシュすることについて情報があります。</link>
            </para>
        </sect3>

        <sect3 id="performance.database.tableMetadata.hardcoding">
            <title>テーブル定義でメタデータをハードコーディングする</title>

            <para>
                1.7.0では、<classname>Zend_Db_Table</classname>は<link
                    linkend="zend.db.table.metadata.caching.hardcoding">テーブルの定義でメタデータをハードコーディングすることをサポート</link>
                することもします。
                これは高度な使用例であり、テーブルのスキーマが変更されそうにないと知っているか、
                または定義を最新状態に保ち続けられる時のみ利用されるべきでしょう。
            </para>
        </sect3>
    </sect2>

    <sect2 id="performance.database.select">
        <title>
            Zend_Db_Selectで生成されたSQLがインデックスにヒットしません。
            どのようにしたらより良く出来ますか？
        </title>

        <para>
            <classname>Zend_Db_Select</classname>は比較的その仕事が得意です。
            ただし、結合や副選択を必要とする複雑なクエリを実行するなら、
            しばしばかなりの素人になりえます。
        </para>

        <sect3 id="performance.database.select.writeyourown">
            <title>自分で最適化したSQLを書く</title>

            <para>
                現実的な唯一の答えは自分で<acronym>SQL</acronym>を書くことです;
                自分で用意できるなら、<classname>Zend_Db</classname>で必ず
                <classname>Zend_Db_Select</classname>を使わずに、<acronym>SQL</acronym>のselect文を調整する
                ことがもっとも完璧に筋の通った道です。
            </para>

            <para>
                <constant>EXPLAIN</constant> をクエリに対して実行して、
                最もパフォーマンスのあるインデックスを本当に当てるまで、
                さまざまな取り組みをテストしてください。
                それからクラスのプロパティーや定数として<acronym>SQL</acronym>をハードコーディングしてください。
            </para>

            <para>
                もし<acronym>SQL</acronym>が変数の引数を必要とする場合、
                <acronym>SQL</acronym>にプレースホルダーを用意してください。
                そして、<acronym>SQL</acronym>に値を挿入するために <methodname>vsprintf()</methodname>
                と <methodname>array_map()</methodname> の組み合わせを利用してください。
            </para>

            <programlisting language="php"><![CDATA[
// $adapter はDBアダプターです。Zend_Db_Tableでは、
// $this->getAdapter() を使ってそれを参照します
$sql = vsprintf(
    self::SELECT_FOO,
    array_map(array($adapter, 'quoteInto'), $values)
);
]]></programlisting>
        </sect3>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
