php mysql pdo fetch

fetch php



PDO:: fetchAll vs. PDO:: buscar en un bucle (7)

@Arkh

// $data in this case is an array of rows; $data = $stmt->fetchAll(); // $data in this case is just one row after each loop; while($data = $stmt->fetch()){} // Try using $i = 0; while($data[$i++] = $stmt->fetch()){}

La diferencia de memoria debería volverse insignificante

Solo una pregunta rápida.

¿Hay alguna diferencia de rendimiento entre el uso de PDO :: fetchAll () y PDO :: fetch () en un bucle (para grandes conjuntos de resultados)?

Estoy buscando objetos de una clase definida por el usuario, si eso hace alguna diferencia.

Mi suposición inicial sin educación fue que fetchAll podría ser más rápido porque PDO puede realizar múltiples operaciones en una declaración, mientras que mysql_query solo puede ejecutar una. Sin embargo, tengo poco conocimiento del funcionamiento interno de PDO y la documentación no dice nada al respecto, y si fetchAll () es simplemente un bucle del lado de PHP volcado en una matriz.

¿Alguna ayuda?


Como decía Mihai Stancu, casi no hay diferencia en la memoria aunque fetchAll beats fetch + while.

Result : fetchAll : 0.160676956177s, 118539304b fetch : 0.121752023697s, 118544392b

Obtuve los resultados anteriores al ejecutarlos correctamente:

$i = 0; while($data[$i++] = $stmt->fetch()){ // }

¡Así que fetchAll consume menos memoria, pero fetch + while es más rápido! :)


Pequeño punto de referencia con 200k registros aleatorios. Como se esperaba, el método fetchAll es más rápido pero requiere más memoria.

Result : fetchAll : 0.35965991020203s, 100249408b fetch : 0.39197015762329s, 440b

El código de referencia utilizado:

<?php // First benchmark : speed $dbh = new PDO(''mysql:dbname=testage;dbhost=localhost'', ''root'', ''''); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = ''SELECT * FROM test_table WHERE 1''; $stmt = $dbh->query($sql); $data = array(); $start_all = microtime(true); $data = $stmt->fetchAll(); $end_all = microtime(true); $stmt = $dbh->query($sql); $data = array(); $start_one = microtime(true); while($data = $stmt->fetch()){} $end_one = microtime(true); // Second benchmark : memory usage $stmt = $dbh->query($sql); $data = array(); $memory_start_all = memory_get_usage(); $data = $stmt->fetchAll(); $memory_end_all = memory_get_usage(); $stmt = $dbh->query($sql); $data = array(); $memory_end_one = 0; $memory_start_one = memory_get_usage(); while($data = $stmt->fetch()){ $memory_end_one = max($memory_end_one, memory_get_usage()); } echo ''Result : <br/> fetchAll : '' . ($end_all - $start_all) . ''s, '' . ($memory_end_all - $memory_start_all) . ''b<br/> fetch : '' . ($end_one - $start_one) . ''s, '' . ($memory_end_one - $memory_start_one) . ''b<br/>'';


Pero seguramente si está almacenando los datos obtenidos en una matriz, ¿el uso de la memoria será igual?

<?php define(''DB_HOST'', ''localhost''); define(''DB_USER'', ''root''); define(''DB_PASS'', ''''); // database to use define(''DB'', ''test''); try { $dbh = new /PDO(''mysql:dbname=''. DB .'';host=''. DB_HOST, DB_USER, DB_PASS); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = ''SELECT * FROM users WHERE 1''; $stmt = $dbh->query($sql); $data = array(); $start_all = microtime(true); $data = $stmt->fetchAll(); $end_all = microtime(true); $stmt = $dbh->query($sql); $data = array(); $start_one = microtime(true); while($data = $stmt->fetch()){} $end_one = microtime(true); // Second benchmark : memory usage $stmt = $dbh->query($sql); $data = array(); $memory_start_all = memory_get_usage(); $data = $stmt->fetchAll(); $memory_end_all = memory_get_usage(); $stmt = $dbh->query($sql); $data = array(); $memory_end_one = 0; $memory_start_one = memory_get_usage(); while($data[] = $stmt->fetch()){ $memory_end_one = max($memory_end_one, memory_get_usage()); } echo ''Result : <br/> fetchAll : '' . ($end_all - $start_all) . ''s, '' . ($memory_end_all - $memory_start_all) . ''b<br/> fetch : '' . ($end_one - $start_one) . ''s, '' . ($memory_end_one - $memory_start_one) . ''b<br/>''; } catch ( PDOException $e ) { echo $e->getMessage(); } ?> Result : fetchAll : 2.6941299438477E-5s, 9824b fetch : 1.5974044799805E-5s, 9824b


Sé que este es un tema viejo, pero me encuentro con la misma pregunta. Después de haber ejecutado mi propio "punto de referencia" y leer lo que otros escribieron aquí, llegué a la conclusión de que no se trata de una ciencia exacta y, si bien uno debe esforzarse por escribir la calidad, el código de luz, no tiene sentido perder demasiado tiempo al principio. del proyecto.

Mi sugerencia es: recopilar datos ejecutando el código (en beta?) Durante un tiempo y luego comenzar a optimizar.

En mi punto de referencia simple (solo el tiempo de ejecución comprobado) obtuve resultados que varían entre 5% y 50% AMBAS formas. Ejecuto ambas opciones en el mismo script, pero cuando ejecuto fetch + while primero ha sido más rápido que fetchall y viceversa. (Sé que debería haberlos ejecutado solos y cientos de veces obtener la mediana y la media y luego comparar, pero, como he dicho al principio, llegué a la conclusión de que en mi caso es demasiado temprano para comenzar a hacerlo).


Una cosa sobre PHP que he descubierto que es cierta casi siempre es que una función que implementes a ti mismo casi siempre será más lenta que el equivalente de PHP. Esto se debe a que cuando algo se implementa en PHP no tiene todas las optimizaciones de tiempo de compilación que C tiene (en qué PHP está escrito) y hay una sobrecarga alta de llamadas a funciones de PHP.


todos los puntos de referencia que miden la "huella de memoria" son incorrectos por la simple razón.

PDO por defecto carga todas las cosas en la memoria y no le importa si usa fetch o fetchAll. Para obtener realmente beneficios de la consulta sin búfer, debe indicar a PDO que use consultas sin búfer:

$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

En ese caso, verá una gran diferencia en la huella de memoria de la secuencia de comandos