# 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)
    );