質問

いくつかの DB ルーチンを作成しており、準備されたステートメントを使用しています。私の環境はPHP5のPDOです。

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

私の質問はパフォーマンスの部分についてです。

以下に、製品 ID を取得してその価格を返す getPrice 関数の 2 つの実装があります。

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";
役に立ちましたか?

解決

私が理解しているところによると、プリペアド ステートメントは、同じステートメントであれば、生成された SQL プランを再利用するため、データベースは同じプリペアド ステートメントを参照し、データベースにクエリを実行する方法を理解する作業を行う必要がありません。準備されたステートメントを保存するという余分な作業が必要になると思います。 Product::getPrice_A これは、パフォーマンスの問題ではなく、コードがわかりにくくなる可能性があるため、通常はあまり役に立ちません。パフォーマンスを扱うときは、問題を示す実際の統計がある場合は、コードの明確さに焦点を当て、次にパフォーマンスに焦点を当てるのが常に最善であると感じます。

私なら、「はい、余分な作業は必要ありません」と言うでしょう (本当にパフォーマンスが向上するかどうかは関係ありません)。また、私はそれほど DB の専門家ではありませんが、準備されたステートメントのパフォーマンスの向上は他の人から聞いたものであり、それはコード レベルではなくデータベース レベルです (つまり、コードが実際にパラメータ化されたステートメントを呼び出している場合)実際の DB の場合、DB はこれらの実行プランのキャッシュを実行できます...ただし、データベースによっては、パラメータ化されたステートメントがなくても利点が得られる場合があります)。

とにかく、データベースのパフォーマンスの問題を本当に心配している (または発生している) 場合は、キャッシュ ソリューションを検討する必要があります。その中で私が強くお勧めしたいのは memcached. 。このようなソリューションを使用すると、クエリ結果をキャッシュすることができ、頻繁にアクセスするものについてはデータベースにアクセスすることさえありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top