Domanda

Ok, ecco una per i pro:

Per un paio d'anni, ho lavorato per conto mio PHP ORM implementazione / ActiveRecord che ho chiamato Pork.dbObject.

E 'loosly basa sul' rendere il proprio sito con le rotaie in 5 minuti di film che abbiamo visto tutti un paio di anni fa. Si possono fare cose come:

$clients = dbObject::Search("Client", array("ID > 500")); 

o

$client = new Client(218); // fetch row with id 218 from client table

o

$projects = $client->Find('Project');

In questo modo recuperare una o più righe dal database, avvolgerli in un DBOBJECT e restituirli in un array, o return false di non ci sono risultati.

Tutto questo ha lavorato perfettamente in decine di siti e backend, ma ora il mio collega sta usando per creare un enorme LogParser e qui inizia i problemi di utilizzo della memoria ..

Le query che corre possono restituire oltre 20.000 righe, forse anche di più, che non è naturalmente una cosa molto buona per avvolgere in un involucro oggetto tutto in una volta e di ritorno, un singolo array.

La soluzione ovvia sarebbe quella di restituire un oggetto che implementa l' Iterator interfacciare invece che una matrice. Non dovrebbe prendere immediatamente tutti i record dal gruppo di risultati, ma basta tenere la risorsa risultato per la query di database generato e utilizzare mysql_fetch_ * internamente quando si attraversa l'oggetto come se fosse un array.

Ora arriviamo alla mia vera domanda: Posso, senza problemi solo fare questo? Sono banche dati in grado di gestire più gruppi di risultati aperti, e mescolarle e tenerli in memoria per un po '?

Per esempio, prendere 20 oggetti, loop, lasciate ciascuno di questi 20 fetch altri 5, goduto a loro volta anche recuperare altri 3. Questo creerebbe un ciclo in cui verrà mantenuta in memoria una serie di diverse maniglie di risultato.

Lo so che non posso serializzare uno di questi oggetti, ma sarò in grado di implementare questo senza alcun problema in PHP5, o saranno interfacce di database darmi problemi?

È stato utile?

Soluzione

Dipende da quale database si sta utilizzando e la configurazione del database.

Per MySQL è necessario assicurarsi di utilizzare le query buffered. In PDO si imposta in questo modo:

$myPdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);

Ciò significa che tutti i dati saranno inviati al client (non lo stesso di andare a prendere tutto in PHP).

L'altro (probabilmente peggiore) alternativa è quella di aprire una nuova connessione al database ogni volta che si rileva una query in esecuzione con un set di risultati ancora aperto.

Il normale mysql_query() utilizza una query tamponata, in modo che funzionerà con più set di risultati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top