2008-09-10 4 views
5

J'écris des routines DB et j'utilise des instructions préparées. Mon environnement est PDO avec PHP5. Je comprends que les instructions préparées fournissent principalement un avantage en termes de performances, ainsi que certains bonus auxiliaires, tels que l'absence de données d'entrée d'échappement SQL manuelles.Comment fonctionnent les instructions préparées?

Ma question concerne la partie performance.

J'ai deux implémentations d'une fonction getPrice ci-dessous qui prend un identifiant de produit et retourne son prix. GetPrice_A réutilise le même objet PDOStatement à travers les appels suivants au cours de la même exécution de script.

Est-ce nécessaire ou recommandé? Si oui, y a-t-il un moyen d'éviter de dupliquer ce code supplémentaire sur chaque get *() dans chaque modèle? GetPrice_B crée un nouvel objet PDOStatement à chaque appel.

Le SGBD reconnaîtra-t-il que cette déclaration a déjà été préparée et qu'il sera encore possible d'ignorer certains travaux? En d'autres termes, cette mise en œuvre tire-t-elle profit des avantages de performance des états préparés? Après avoir écrit tout cela et lu, j'imagine que getPrice_B est bien et getPrice_A offre un avantage négligeable en plus de cela, ce qui peut ou peut ne pas valoir la complication supplémentaire.

Je voudrais toujours entendre à coup sûr de quelqu'un plus bien informé cependant. Supposons que $pdo est un objet PDO connecté et valide dans les exemples ci-dessous.

<?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"; 

Répondre

3

D'après ce que je comprends, les déclarations préparées réutilisera le plan SQL généré si elle est la même déclaration, de sorte que la base de données verra la même déclaration préparée et ne pas avoir à faire le travail pour comprendre comment interroger la base de données. Je dirais que le travail supplémentaire de sauvegarde de l'instruction préparée dans Product::getPrice_A n'est généralement pas très utile, d'autant plus qu'il peut masquer le code plutôt qu'un problème de performance. En ce qui concerne les performances, je pense qu'il est toujours préférable de se concentrer sur la clarté du code, puis sur les performances lorsque vous avez des statistiques réelles qui indiquent un problème.

Je dirais "oui, le travail supplémentaire n'est pas nécessaire" (indépendamment du fait que cela booste vraiment les performances). De plus, je ne suis pas un très grand expert DB, mais le gain de performance des instructions préparées est quelque chose que j'ai entendu d'autres, et c'est au niveau de la base de données, pas du code (donc si le code invoque une instruction paramétrée). DB réel, alors la base de données peut faire cette mise en cache de plan d'exécution ... bien que selon la base de données, vous pouvez obtenir le bénéfice même sans l'instruction paramétrée). De toute façon, si vous êtes vraiment inquiet (et voir) les problèmes de performance de base de données, vous devriez regarder dans une solution de mise en cache ... que je recommande fortement memcached. Avec une telle solution, vous pouvez mettre en cache les résultats de votre requête et ne pas même atteindre la base de données pour les éléments auxquels vous accédez fréquemment.

Questions connexes