Frage

Ich schreibe einige DB-Routinen und verwende vorbereitete Anweisungen.Meine Umgebung ist PDO mit PHP5.

Ich verstehe, dass vorbereitete Anweisungen in erster Linie einen Leistungsvorteil bieten, aber auch einige zusätzliche Vorteile mit sich bringen, z. B. dass Eingabedaten nicht manuell mit SQL-Escapezeichen versehen werden müssen.

Meine Frage betrifft den Leistungsteil.

Ich habe unten zwei Implementierungen einer getPrice-Funktion, die eine Produkt-ID annimmt und ihren Preis zurückgibt.

getPrice_A verwendet dasselbe PDOStatement-Objekt bei nachfolgenden Aufrufen innerhalb derselben Skriptausführung wieder.Ist dies notwendig oder empfehlenswert?Wenn ja, gibt es eine Möglichkeit, die Duplizierung dieses zusätzlichen Codes für jedes einzelne get*() in jedem einzelnen Modell zu vermeiden?

getPrice_B erstellt bei jedem Aufruf ein neues PDOStatement-Objekt.Wird das DBMS erkennen, dass diese Erklärung bereits vorbereitet wurde, und dennoch einige Arbeiten überspringen können?Mit anderen Worten: Nutzt diese Implementierung die Leistungsvorteile vorbereiteter Anweisungen ordnungsgemäß aus?

Nachdem ich das alles aufgeschrieben und durchgelesen habe, stelle ich mir vor, dass getPrice_B in Ordnung ist und getPrice_A darüber hinaus einen vernachlässigbaren Vorteil bietet, der die zusätzliche Komplikation vielleicht wert ist oder auch nicht.

Ich würde jedoch auf jeden Fall gerne von jemandem hören, der sich besser auskennt.

Annehmen, dass $pdo ist in den folgenden Beispielen ein gültiges, verbundenes PDO-Objekt.

<?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";
War es hilfreich?

Lösung

Von dem, was ich verstehe, werden wieder verwenden vorbereitete Anweisungen, die generierten SQL-Plan, wenn es die gleiche Aussage ist, so dass die Datenbank die gleiche vorbereitete Anweisung sehen und nicht die Arbeit machen müssen, um herauszufinden, wie die Datenbank abzufragen. Ich würde sagen, die zusätzliche Arbeit, die vorbereitete Anweisung in Product::getPrice_A Speicher der Regel nicht sehr hilfreich ist, mehr, weil es den Code anstatt eine Frage der Leistung verschleiern kann. Wenn es mit Leistung zu tun, ich glaube, es ist immer am besten auf Code Klarheit zu konzentrieren und dann Leistung, wenn Sie echte Statistiken, die auf ein Problem hinweisen.

Ich würde sagen: „Ja, die zusätzliche Arbeit ist nicht notwendig“ (unabhängig davon, ob es wirklich steigert die Leistung). Auch ich bin kein sehr großer DB-Experte, aber der Performance-Gewinn von Prepared Statements ist etwas, was ich von anderen gehört, und es ist auf Datenbankebene, nicht die Code-Ebene (also wenn der Code tatsächlich eine parametrisierte Aussage über die Berufung ist DB, dann kann die DB diesen Ausführungsplan Caching tun ... obwohl auf der Datenbank abhängig, können Sie den Vorteil auch ohne die parametrisierte Anweisung) erhalten.

Wie auch immer, wenn Sie wirklich besorgt über (und zu sehen) Datenbank-Performance-Probleme, sollten Sie eine Caching-Lösung suchen in ... von denen würde ich empfehlen memcached . Mit einer solchen Lösung können Sie Ihre Abfrageergebnisse zwischenspeichern und nicht einmal schlagen die Datenbank für die Dinge, die Sie häufig zugreifen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top