2011-06-24 5 views
5

estoy usando una aplicación concreta de Zend_Db_Table_Abstract:Zend_Db_Table_Abstract concreta para iterar eficientemente a través de un conjunto de filas

class DB_TestClass extends Zend_Db_Table_Abstract { 
    protected $_name = "test.TestData"; 
} 

Si quiero seleccionar todas las filas de la tabla, me parece que tienen una opción:

$t = new DB_TestClass; 
$rowset = $t->fetchAll(); 

Esto devuelve una instancia de Zend_Db_Table_Rowset que tiene una interfaz iterable puede recorrer sin embargo y acceder a cada entrada de fila como una instancia rowClass:

foreach($rowset as $row) { 
    var_dump($row); 
} 

SIN EMBARGO, el conjunto de filas ha cargado cada fila de la base de datos en la memoria (!) En tablas pequeñas esto está bien, pero en tablas grandes - miles de filas, por ejemplo - agota rápidamente la memoria disponible para PHP y el script muere .

¿Cómo puedo, usando Zend_Db, recorrer el conjunto de resultados recuperando una fila de un identificador de instrucciones a la vez, ala mysql_fetch_assoc()? Esto permitiría un acceso eficiente a cualquier cantidad de filas (miles, millones) sin usar una cantidad excesiva de memoria.

Gracias de antemano por cualquier sugerencia.

Respuesta

2

Entonces fetchAll() no es capaz de lo que usted desea. Es necesario utilizar Zend_Db_Select para obtener todos los registros y luego hacer lo que has pretende a través del bucle

 $select = new Zend_Db_Select ($this->getFrontController()->getParam('bootstrap')->getResource ('Db')); 
     $statement = $select->from ('verses')->query(); 
     $statement->execute(); 


     while ($row = $statement->fetch()) 
     { 
      // try something like that 
      $db_row = new Zend_Db_Table_Row (array ('table' => $table, 'data' => $row)); 

      $db_row->text = $db_row->text . '_'; 
      $db_row->save(); 

     } 
+0

Hacer esto significa que pierde la funcionalidad de patrón de puerta de acceso de fila (por lo que en cada $ fila, ya no puede hacer: '$ fila-> campo = "nuevo valor"; $ fila-> guardar();'), que es uno de los beneficios de usar Zend_Db. ¿Hay alguna manera de volver a utilizar su sugerencia anterior? –

+0

Ver mi actualización. Deberia de funcionar. – akond

+0

Ah, y por cierto, eche un vistazo a Zend_Db_Table_Select. Probablemente te quede mejor. – akond

1

¿Puede especificar el propósito de buscar todas las filas? Porque si desea hacer algún tipo de procesamiento en todas las filas de la tabla, entonces, ¿qué formas tiene que obtener todas las filas en la memoria. Por otro lado, si quieres hacer algo como paginación, siempre puedes usar el objeto zend_pagination que simplemente buscará el no limitado. de filas a la vez. O mejor aún puede establecer el desplazamiento y no. de las filas que se van a buscar en la función fetchAll en sí.

+0

Digamos, por ejemplo, quiero ejecutar una instrucción de actualización en cada fila, Ala: '$ de fila > columna = "nuevo valor"; $ row-> save(); 'Llamar a fetchAll con un desplazamiento y número de filas para recuperarlos en conjuntos también es ineficiente (muchos hits de DB, o si cada fila contiene datos de 1MB (posible, si está almacenando blobs), entonces no se necesita mucho para agotar la RAM disponible.) No debería haber una necesidad de buscar en RAM más de una fila a la vez. –

+0

Si está guardando datos muy pesados ​​en la base de datos, tal vez sea hora de usar algo como memcached para almacenar esos datos pesados ​​para evitar viajes redondos al servidor y distribuirlos en varios servidores. Por lo que sé, la clase Abstract Table de Zend Framework usa la función mysql_fetch_assoc solo así que no debería ser una gran diferencia y sí, si hay varias filas para actualizar, entonces debes estar usando el comando "update" directamente, supongo, no hace mucho sentido actualizando cada fila. – Sid

Cuestiones relacionadas