php - statements - sentencias preparadas ventajas y desventajas
¿Cómo funcionan las declaraciones preparadas? (1)
Estoy escribiendo algunas rutinas DB y estoy usando declaraciones preparadas. Mi entorno es PDO con PHP5.
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 de rendimiento.
Tengo dos implementaciones de una función getPrice a continuación que toma una identificación de 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?
Habiendo escrito todo esto y lo leyó, me imagino que getPrice_B está bien y getPrice_A ofrece un beneficio insignificante además de eso, lo que puede o no valer la pena la complicación adicional.
De todos modos, me gustaría saber con 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";
Por lo que entiendo, las declaraciones preparadas reutilizarán el plan SQL generado si es la misma declaración, por lo que la base de datos verá la misma declaración preparada y no tendrá que hacer el trabajo para 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.
Diría que "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 todas formas, si realmente te preocupan (y ves) los problemas de rendimiento de la base de datos, debes buscar en una solución de almacenamiento en caché ... de la cual recomiendo encarecidamente 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.