5

私はいくつかの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";
4

1 に答える 1

3

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

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

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

于 2008-09-10T19:02:42.663 に答える