# Zend_Dbパフォーマンス

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

## テーブルのメタデータを取得する際にZend_Db_Tableによってもたらされる オーバーヘッドをどのようにしたら減らせますか？

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

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

### メタデータキャッシュの利用

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

`Zend_Db_Table` のドキュメントにメタデータをキャッシュすることについて情報があります。

### テーブル定義でメタデータをハードコーディングする

1.7.0では、`Zend_Db_Table`はテーブルの定義でメタデータをハードコーディングすることをサポート することもします。 これは高度な使用例であり、テーブルのスキーマが変更されそうにないと知っているか、 または定義を最新状態に保ち続けられる時のみ利用されるべきでしょう。

## Zend_Db_Selectで生成されたSQLがインデックスにヒットしません。 どのようにしたらより良く出来ますか？

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

### 自分で最適化したSQLを書く

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

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

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

    // $adapter はDBアダプターです。Zend_Db_Tableでは、
    // $this->getAdapter() を使ってそれを参照します
    $sql = vsprintf(
        self::SELECT_FOO,
        array_map(array($adapter, 'quoteInto'), $values)
    );