2009-02-23 24 views
6

Sto riscontrando seri problemi con le funzioni dell'oggetto dati PHP. Sto cercando di eseguire il ciclo di un set di risultati considerevole (~ 60k righe, ~ 1gig) utilizzando una query memorizzata nel buffer per evitare di recuperare l'intero set.PHP PDO Buffered query problem

Non importa quello che faccio, lo script si blocca solo sul PDO :: query() - sembra che la query sia in esecuzione unbuffered (perché altrimenti il ​​cambiamento nella dimensione del set di risultati 'corregge' il problema?). Ecco il mio codice per riprodurre il problema:

Se limito la domanda con un certo numero ragionevole, funziona benissimo:

$rQuery = $Database->query('SELECT id FROM mytable LIMIT 10'); 

Ho provato a giocare con PDO :: MYSQL_ATTR_MAX_BUFFER_SIZE e dell'uso della DOP :: prepare() e PDO :: execute() pure (sebbene non ci siano parametri nella query precedente), entrambi senza alcun risultato. Qualsiasi aiuto sarebbe apprezzato.

risposta

8

Se ho capito bene, le query memorizzate nel buffer implicano dire a PHP che si desidera attendere l'intero set di risultati prima di iniziare l'elaborazione. Prima del PDO, questo era l'impostazione predefinita e si doveva chiamare mysql_unbuffered_query se si desidera gestire immediatamente i risultati.

Perché questo non è spiegato nella pagina del driver MySQL per PDO, non lo so.

+0

Wow bene che sono un idiota . Non so cosa mi ha dato l'impressione opposta. – Stewart

+0

Tecnicamente, una query "bufferizzata" significa che la libreria client MySQL estrae l'intero set di risultati dallo stream TCP prima di restituirla all'utente. – staticsan

+0

Hmm, pensavo che il manuale coprisse la differenza tra buffered/unbuffered (stile mysql) e fetch/fetchAll (stile PDO), ma guardando di nuovo no. Se si desiderano ulteriori informazioni di base, è possibile trovare le seguenti informazioni utili: http://netevil.org/blog/2008/06/slides-pdo –

1

Si potrebbe provare a dividerlo in pezzi che non sono abbastanza grande da causare problemi:

<?php  
$id = 0; 
$rQuery = $Database->query('SELECT id FROM mytable ORDER BY id ASC LIMIT 100'); 

do { 
    stuff($rQuery); 
    $id += 100; 
} while ($rQuery = $Database->query(
      'SELECT id FROM mytable ORDER BY id ASC LIMIT 100 OFFSET '.$id 
     ) 
     ); 
?> 

... si ottiene l'idea, in ogni caso.

-1

O forse si potrebbe provare funzioni di MySQL, invece:

while ($row = mysql_fetch_row($query)) { 
... 
} 

che sarà sicuramente più veloce, dal momento che la dichiarazione foreach fa un'impressione di utilizzare fetchAll() invece fetch() ogni riga

+1

Le funzioni di mysql_ sono deprecate e non dovrebbero essere utilizzate – vvondra