<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 20876 -->
<!-- Reviewed: no -->
<sect1 id="performance.database">
    <title>Zend_Db Performance</title>

    <para>
        <classname>Zend_Db</classname> ist ein Datenbank Abstraktion Layer und ist dazu gedacht
        eine gemeinsame <acronym>API</acronym> für <acronym>SQL</acronym> Operationen zu bieten.
        <classname>Zend_Db_Table</classname> ist ein Table Data Bateway, dazu gedacht übliche
        Tabellen-artige Datenbank Operationen zu abstrahieren. Wegen Ihrer abstrakten Natur und der
        "Magie" die Sie versteckt haben um Ihre Operationen durchführen zu können, können Sie
        manchmal auch zu Geschwindigkeitsnachteilen führen.
    </para>

    <sect2 id="performance.database.tableMetadata">
        <title>
            Wie kann ich den Overhead reduzieren der von Zend_Db_Table eingeführt wird um die
            Metadaten der Tabelle zu erhalten?
        </title>

        <para>
            Um die Verwendung so einfach wie möglich zu halten, und auch sich konstant ändernde
            Schemata wärend der Entwicklung zu unterstützen, macht
            <classname>Zend_Db_Table</classname> einiges an Magie unter seinem Hut: bei der ersten
            Verwendung, holt es das Tabellenschema und speichert es im Objekt. Diese Operation ist
            normalerweise sehr teuer, unabhängig von der Datenbank -- das zu einer Schwachstelle in
            der Produktion führen kann.
        </para>

        <para>
            Glücklicherweise gibt es Techniken um die Situation zu verbessern.
        </para>

        <sect3 id="performance.database.tableMetadata.cache">
            <title>Den Metadaten Cache verwenden</title>

            <para>
                <classname>Zend_Db_Table</classname> kann optional <classname>Zend_Cache</classname>
                verwenden um die Metadaten der Tabelle zu cachen. Dieser ist typischerweise
                schneller im Zugriff und nicht so teuer wie das holen der Metadaten von der Tabelle
                selbst.
            </para>

            <para>
                Die Dokumentation von <link
                    linkend="zend.db.table.metadata.caching"><classname>Zend_Db_Table</classname>
                    enthält Informationen über das Cachen der Metadaten</link>.
            </para>
        </sect3>

        <sect3 id="performance.database.tableMetadata.hardcoding">
            <title>Die Metadaten in der Tabellendefinition fix codieren</title>

            <para>
                Mit 1.7.0, bietet <classname>Zend_Db_Table</classname> auch
                <link linkend="zend.db.table.metadata.caching.hardcoding">Unterstützung für fix
                kodierte Metadaten in der Tabellen Definition</link>. Das ist ein schwierigerer
                Verwendungsfall, und sollte nur dann verwendet werden wenn man weiß das sich das
                Tabellenschema nicht ändern wird, oder das man fähig ist die Definition immer
                up-to-date zu halten.
            </para>
        </sect3>
    </sect2>

    <sect2 id="performance.database.select">
        <title>
            SQL die mit Zend_Db_Select erzeugt wurde greift nicht auf die Indezes zu; wie kann man
            das besser machen?
        </title>

        <para>
            <classname>Zend_Db_Select</classname> ist relativ gut in seinem Job. Trotzdem kann es,
            wenn man komplexe Abfragen benötigt die Joins oder Unterabfragen enthalten, sehr naiv
            sein.
        </para>

        <sect3 id="performance.database.select.writeyourown">
            <title>Selbst getuntes SQL schreiben</title>

            <para>
                Die einzige echte Antwort ist es eigenes <acronym>SQL</acronym> zu schreiben;
                <classname>Zend_Db</classname> erfordert nicht die Verwendung von
                <classname>Zend_Db_Select</classname>, als ist die Verwendung von eigenen, getunten
                <acronym>SQL</acronym> Select Statements, eine perfekte und legitime Anwendung.
            </para>

            <para>
                Lasse <constant>EXPLAIN</constant> auf den Abfragen laufen, und teste eine Vielzahl
                von Möglichkeiten bis man die eigenen Indezes auf dem besten und performantesten
                Weg trifft -- und dann sollte dieses <acronym>SQL</acronym> als Klasseneigenschaft
                oder Konstante fix kodiert werden.
            </para>

            <para>
                Wenn das <acronym>SQL</acronym> variable Argumente benötigt, können Platzhalter im
                <acronym>SQL</acronym> verwendet werden und in einer Kombination von
                <methodname>vsprintf()</methodname> und <methodname>array_walk()</methodname>
                verwendet werden um Werte in das <acronym>SQL</acronym> zu injizieren:
            </para>

            <programlisting language="php"><![CDATA[
// $adapter ist der DB Adapter. In Zend_Db_Table ist es durch
// Verwendung von $this->getAdapter() zu empfangen.
$sql = vsprintf(
    self::SELECT_FOO,
    array_walk($values, array($adapter, 'quoteInto'))
);
]]></programlisting>
        </sect3>
    </sect2>
</sect1>
