2012-05-05 11 views
9

Supponendo che hoZend_Db: fetchAll() o query()/fetch() per un enorme numero di record

$db is an instance of Zend_Db_Adapter_Abstract and 
$sql = 'SELECT blah blah FROM table' will return a huge number of records. 

Ci sono due frammenti di codice per elaborare i dati restituiti nel modo seguente.

// Code fragment 1 (let's call it C1). 
$results = $db->fetchAll($sql); 
foreach ($results as $row) { 
    // Process $row 
} 

// Code fragment 2 (let's call it C2). 
$stmt = $db->query($sql); 
while ($row = $stmt->fetch()) { 
    // Process $row 
} 

La mia comprensione è che C1 caricherà tutti i dati restituiti in $ risultati. Quindi, un enorme dato viene caricato nella memoria PHP. Di seguito sono le mie domande.

  1. C2 carica tutti i dati nella memoria PHP o li elabora uno alla volta come prepara/esegue?
  2. Supponendo che non ci siano altre opzioni, C1 o C2 è un'opzione migliore?

Grazie!

risposta

14

La tua impressione è corretta. Almeno se stai usando il driver PDO, -> fetch() legge i risultati senza buffer, mentre -> fetchAll() restituisce tutti i dati in un grande array.

Si noti che se si utilizza -> fetch(), è necessario fare attenzione a ciò che si tenta di fare all'interno del ciclo. Non puoi eseguire query aggiuntive sulla stessa connessione mentre hai ancora un set di risultati senza buffer.

Quindi, se il tuo piano è di aggiornare le stesse righe all'interno del ciclo, dovrai trovare un modo per ritardare l'esecuzione degli aggiornamenti (accodando poi in qualche modo) fino a quando non sei uscito dal ciclo.

+0

Grazie per il vostro allarme sull'uso fetch() :) – peidiam

10

Per recuperare una riga dal risultato set, utilizzare il metodo fetch() dell'oggetto dichiarazione. Reference

$sql = 'SELECT blah blah FROM table'; 
$stmt = $db->query($sql); 
while ($row = $stmt->fetch()) { 
    // Process $row 
} 

nel precedente Esempio $stmt = $db->query($sql); recuperato il resultset nella memoria e fetch viene utilizzato per recuperare la riga corrente nel loop dal resultset, che sposta il cursore alla riga successiva fino alla la ultima riga nel resultset.

Per recuperare tutte le righe del set di risultati in un unico passaggio, utilizzare il metodo fetchAll() . Ciò equivale a chiamare il metodo fetch() in un ciclo e restituire tutte le righe in un array.

$sql = 'SELECT blah blah FROM table'; 
$stmt = $db->query($sql); 
$rows = $stmt->fetchAll(); 
echo $rows[0]['col1']; // The first field/column from the first row 

In alternativa è possibile utilizzare

.... 
$table = new Mytable(); 
// Find a single row Returns a Rowset 
$rows = $table->find(1234); 

// Find multiple rows Also returns a Rowset 
$rows = $table->find(array(1234, 5678)); 

Riferimento:Zend_Db_Table..

Per ulteriori informazioni:Fetching a Row..

Penso che fetchAll() sia più veloce perché recupera tutti i dati in un unico passaggio e restituisce un array ma consuma più memoria ma fetch() consuma meno memoria ma recupera i dati uno per uno.

L'API per le operazioni di recupero è stato sostituito da consentire un oggetto Zend_Db_Table_Select per modificare la query. Tuttavia, l'uso deprecato di dei metodi fetchRow() e fetchAll() sarà continuare a funzionare senza modifiche.

Più Riferimento:Here.

+1

I tuoi dati è completa e disponibile. Grazie! – peidiam

Problemi correlati