2008-09-10 24 views
5

私はいくつかのDBルーチンを書いています。私は準備済みの文を使用しています。私の環境はPHP5のPDOです。準備文はどのように機能しますか?

私は、準備されたステートメントは、主に、パフォーマンス上の利点と、手動でSQLエスケープ入力データを必要としないなどのいくつかの補助ボーナスを提供することを理解しています。

私の質問は、パフォーマンスに関するものです。

下記のgetPrice関数の2つの実装では、製品IDをとり、その価格を返します。

getPrice_Aは、同じスクリプト実行内で後続のコール全体で同じPDOStatementオブジェクトを再利用します。これは必要か推奨ですか?もしそうなら、すべての単一のモデルですべての単一のget *()にこの余分なコードを複製しないようにする方法はありますか?

getPrice_Bは、すべての呼び出しで新しいPDOStatementオブジェクトを作成します。 DBMSはこのステートメントがすでに準備されていると認識し、依然としていくつかの作業をスキップできますか?言い換えれば、この実装は適切にプリペアド・ステートメントのパフォーマンス上の利点を利用していますか?

これをすべて書き出して読んだら、getPrice_Bはうまくいくと思いますが、getPrice_Aは余分な複雑さに値するかもしれません。

私はまだ誰かからもっと知っていると聞いてみたいと思います。

以下の例では、$pdoが有効な接続済みPDOオブジェクトであるとします。

<?php 
class Product { 
    static function &getPrice_A($id) { 
     static $stmt; 
     if (!$stmt) { 
      $stmt = $pdo->prepare('SELECT price FROM products WHERE id = ?'); 
     } 
     $stmt->execute(array($id)); 
     return $stmt->fetchColumn(0); 
    } 

    static function &getPrice_B($id) { 
     $stmt = $pdo->prepare('SELECT price FROM products WHERE id = ?'); 
     $stmt->execute(array($id)); 
     return $stmt->fetchColumn(0); 
    } 
} 

// example usage: 
$price = Product::getPrice(4982); 
echo "Product 4982 costs $price\n"; 

答えて

3

私が理解から、それは同じ文であればプリペアドステートメントは、生成されたSQL計画を再利用しますので、データベースに照会する方法を見つけ出すために仕事をしなければならない同じプリペアドステートメントを見ていないだろうデータベース。準備されたステートメントをProduct::getPrice_Aに保存する余分な作業は、パフォーマンスの問題ではなくコードを隠す可能性があるため、一般的にはあまり役に立ちません。パフォーマンスを扱う際には、問題を示す実際の統計がある場合は、コードの明快さとパフォーマンスに焦点を当てることが常にベストであると感じています。

私は「はい、余分な作業は不要です」と言っています(実際にパフォーマンスを向上させるかどうかは関係ありません)。また、私は非常に大きなDBのエキスパートではありませんが、プリペアドステートメントのパフォーマンスの向上は、他の人から聞いたことであり、コードレベルではなくデータベースレベルにあります(コードが実際に実際のDBでは、DBはこれらの実行プランのキャッシュを行うことができます...データベースによっては、パラメータ化された文もなくても利益を得ることができます)。

とにかく、データベースパフォーマンスの問題が本当に心配であれば、キャッシングソリューションを調べる必要があります。このうち、memcachedを強くおすすめします。このようなソリューションでは、クエリ結果をキャッシュし、頻繁にアクセスするものについてはデータベースにアクセスすることさえできません。

関連する問題