2008-09-10 26 views
5

Estoy escribiendo algunas rutinas DB y estoy usando declaraciones preparadas. Mi entorno es PDO con PHP5.¿Cómo funcionan las declaraciones preparadas?

Entiendo que las declaraciones preparadas proporcionan principalmente un beneficio de rendimiento, así como algunas bonificaciones auxiliares, como no tener que escanear manualmente los datos de entrada de SQL.

Mi pregunta es sobre la parte del rendimiento.

Tengo dos implementaciones de una función getPrice a continuación que toma una identificación del producto y devuelve su precio.

getPrice_A reutiliza el mismo objeto PDOStatement en llamadas posteriores dentro de la misma ejecución del script. ¿Es esto necesario o recomendado? Si es así, ¿hay alguna forma de evitar la duplicación de este código adicional en cada get *() en cada modelo?

getPrice_B crea un nuevo objeto PDOStatement en cada llamada. ¿El DBMS reconocerá que esta declaración ya ha sido preparada y aún podrá omitir algún trabajo? En otras palabras, ¿esta implementación aprovecha adecuadamente los beneficios de rendimiento de las declaraciones preparadas?

Después de escribir todo esto y leerlo, me imagino que getPrice_B está bien y getPrice_A proporciona un beneficio insignificante además de eso, que puede o no valer la pena la complicación adicional.

Todavía me gustaría tener la certeza de alguien más conocedor.

Suponga que $pdo es un objeto PDO válido y conectado en los ejemplos a continuación.

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

Respuesta

3

Por lo que entiendo, declaraciones preparadas reutilizará el plan SQL generado si se trata de la misma declaración, por lo que la base de datos va a ver la misma declaración preparada y no tener que hacer el trabajo de averiguar cómo consultar la base de datos. Yo diría que el trabajo adicional de guardar la declaración preparada en Product::getPrice_A no suele ser muy útil, más porque puede oscurecer el código en lugar de un problema de rendimiento. Cuando se trata de rendimiento, creo que siempre es mejor enfocarse en la claridad del código y luego en el rendimiento cuando se tienen estadísticas reales que indican un problema.

Yo diría "sí, el trabajo adicional es innecesario" (independientemente de si realmente aumenta el rendimiento). Además, no soy un gran experto en DB, pero la ganancia de rendimiento de las declaraciones preparadas es algo que escuché de otros, y está en el nivel de la base de datos, no en el nivel de código (por lo tanto, si el código está invocando una declaración parametrizada en el DB real, entonces el DB puede hacer el almacenamiento en caché de estos planes de ejecución ... aunque dependiendo de la base de datos, puede obtener el beneficio incluso sin la sentencia parametrizada).

De todos modos, si está realmente preocupado por (y ver) problemas de rendimiento de la base de datos, debe buscar en una solución de almacenamiento en caché ... de la cual recomendaría memcached. Con esta solución, puede almacenar en caché los resultados de su consulta y ni siquiera acceder a la base de datos para acceder a los elementos a los que accede con frecuencia.

Cuestiones relacionadas