2012-07-29 16 views
8

Cuando realicé una consulta en la base de datos y obtuve los resultados en mysqli_result, el uso de memoria es extremadamente pequeño. Sin embargo, cuando busco todas las filas en los resultados de la consulta en una matriz asociativa, el uso de memoria se vuelve extremadamente alto.PHP: cómo se almacenan los resultados de la consulta en mysqli_result

<?php 
    require_once("../config.php"); //db connection config 
    $db = new mysqli(DB_HOST,DB_USER,DB_PASSWORD,DB_DBASE); 

    $query ="select * from table_name"; 
    if($r = $db->query($query)){ 
    echo "MEMORY USAGE before : ". memory_get_usage()."<br><br>"; 
    $rows = array(); 
    while($row = $r->fetch_assoc()){ 

     $rows[]= $row; 
    } 
    echo "MEMORY USAGE after : ". memory_get_usage()."<br><br>"; 


    //before: 660880 
    //after: 114655768 
    // # of records: around 30 thousands 
?> 

tiene sentido para mí que almacenar esta cantidad de resultados es muy consumo de memoria, pero me pregunto cómo es que mysqli_result es tan pequeño. No puede ser que los resultados se consulten con la base de datos cada vez que se llame a fetch_assoc. Entonces, ¿dónde están los resultados almacenados en la memoria?

+1

Leí en alguna parte que las funciones 'mysql_ *' recuperan todas las filas de resultados del servidor a la vez. Sin embargo, PDO (y probablemente mysqli) recuperar cada fila a pedido. Entonces, con cada llamada a buscar, va a consumir un poco de memoria. Pero usted almacena cada fila en una matriz, por lo que tiene sentido que su uso de memoria se acumule. –

+0

¿Quiere decir que con cada llamada a buscar, mysqli consultará la base de datos para obtener el resultado? – spchuang

+1

Según entiendo, cuando llama a 'query()' MySQL realiza la consulta y se prepara para devolver todas las filas de resultados a PHP. Sin embargo, si mysqli es como PDO (al menos el valor predeterminado de PDO), entonces no comenzará a recibir filas hasta que llame a fetch. A menos que llame a 'fetchAll()', cada fila se recuperará de a una por vez. Esto significa que su uso de memoria se debe a que guardó los resultados en una matriz, no a causa de mysqli. –

Respuesta

2

Hay una GRAN diferencia entre obtener resultados y almacenar un puntero a un recurso.

Si echo $r; antes de su primera llamada al memory_get_usage();, se dará cuenta de que es solo un puntero. Este es el puntero a su conjunto de resultados. Hasta que fetch sus resultados, el conjunto de resultados no se almacenará en la memoria.

Le sugiero que ejecute fetchAll() por lo que está tratando de hacer. Esto dará como resultado un método para acceder a todos sus resultados con un mejor rendimiento, ya que está empeñado en la extensión mysqli (Biblioteca C) en lugar de un bucle en PHP.

También puede usar la función de resultados gratuitos para borrar los resultados de la memoria cuando haya terminado con ellos. Esto es como cerrar un cursor en Java si está familiarizado.

+0

Gracias. ¡Esto es muy útil! :) – spchuang

+0

Entonces, ¿por qué no se agrega realmente el recurso al uso de la memoria?El recurso está usando espacio de memoria ... ¿O está escrito en el disco o algo así? –

+0

Al hacer eco de '$ r' antes de invocar fetch, MySQL habría asignado espacio para los resultados de la consulta, pero no para PHP. PHP solo asignará los resultados a su espacio de memoria cuando llame a fetch. –

1

creo que deberías hacerlo a este lugar:

while($row = $r->fetch_assoc()){ 
    //Do whatever you need with the record, then: 
    unset($row); 
} 

La forma en que envió está reuniendo una enorme variedad en $rows, uso de memoria y lo refleja.

+0

Sé lo que quieres decir y esa es definitivamente la intención original de fetch_assoc(). El problema es que voy a buscar el resultado y hacer algo con él y pasarlo a la vista (en sentido MVC) para visualizar los registros. Creo que podría cambiar mi implementación para que se pase un registro para ver a la vez. – spchuang

+0

Eso sería sabio :) – Niloct

+0

Gracias. Es un problema porque he estado tratando de evitar que la vista se comunique directamente con los modelos, así que también tengo un controlador en el medio para pasar datos. Lo que necesito hacer entonces es crear una plantilla de vista muy pequeña para mostrar cada registro ... – spchuang

Cuestiones relacionadas