Se ti aspetti davvero che la tua tabella cresca, dovresti iniziare a pensare al batch del processo, a fare i tuoi calcoli in fasi. Il modo più semplice sarebbe avere una tabella secondaria che possa contenere l'id utente e il timestamp di quando l'utente è stato elaborato per l'ultima volta, e limitare lo script cron a scorrere, ad esempio, 500 utenti per volta. I numeri esatti dipenderanno da cosa stai facendo esattamente, sarà un po 'di prova ed errore.
Se decidi di eseguire il batch del processo, dovrai ovviamente eseguire lo script cron più di una volta, è abbastanza facile, elaborare solo utenti che non sono stati elaborati di recente (controllando il timestamp) e, ovviamente, registrarli come elaborati in seguito. Se i tuoi ID utente sono sequenziali, potresti risparmiarti la fatica di registrare ogni id utente elaborato e solo registrare l'ultimo del batch, tuttavia se qualcosa va storto nel mezzo del batch, non avresti alcuna idea di dove si fermò. La tua scelta;)
Quindi devi ottimizzare il tuo ciclo. Inizia con le cose semplici, stai usando o foreach? C'è un'abbondanza di riferimenti che sostengono che uno sia più veloce dell'altro, ma la verità è che dovrai metterli alla prova e scoprire quale è più veloce (se c'è davvero una differenza) per te. Dipende dalla tua versione php, os, e dalle strutture che stai eseguendo in loop (se stai eseguendo il loop di oggetti iterabili, per esempio), e ovviamente dovresti eseguire il test sul server in cui il tuo script vivrà, specialmente se l'ambiente è diverso da il tuo sviluppo locale.
Quindi, è il momento di profilare e ottimizzare i tuoi calcoli. Non ci stai dicendo cosa stai facendo, ma 3.5mb di memoria sembrano un po 'troppo per una singola iterazione. Potrebbe essere che i tuoi calcoli sono così intensi e hai fatto del tuo meglio, o potrebbe esserci qualcosa di ovvio che ti manca, in ogni caso è qualcosa che solo un profiler può dirti.
Sebbene max_execution_time
sia hardcoded a 0 (nessun limite) per la SAPI della CLI, potresti voler limitare il tempo di esecuzione attraverso set_time_limit o ini_set ('max_execution_time') ( stessa cosa) per due motivi:
- Aiuterà a testare lo script tramite il browser, dove c'è un limite (in php.ini). Non sarebbe consigliabile consentire l'accesso del browser allo script di produzione, ma durante lo sviluppo non avrebbe senso impostare cron solo per testare il tuo script.
- Anche se non c'è limite per gli script CLI, non sarebbe male imporre il limite nel caso in cui qualcosa di sconveniente accadesse. I server di database rallentano di tanto in tanto e non si desidera realmente che lo script venga eseguito all'infinito (== finché non esaurisce la memoria).
Se hai problemi di memoria, è ora di fare qualche raccolta dei rifiuti . L'approccio ingenuo sarebbe quello di chiamare gc_collect_cycles alla fine del tuo script, forzando la garbage collection di tutti i cicli esistenti in quel momento. Non sarebbe male se hai unset () risorse di memoria affamate prima mano. Ricorda che i loop php non creano il proprio ambito, ad esempio:
<?php
foreach($array as $key => $value) {
doSomething($value);
}
var_dump($key, $value);
?>
funzionerà, scaricando l'ultimo $key
e $value
del ciclo, il che significa che alla fine del ciclo non ne hai uno ( $array
) ma tre variabili inutilizzate, che verranno raccolte quando php decide che è un buon momento per raccogliere rifiuti. Per forzarlo, fai qualcosa come:
<?php
foreach($array as $key => $value) {
doSomething($value);
}
unset($array, $key, $value);
gc_collect_cycles();
?>
Sono sicuro al 99% che unset($array, $key, $value);
non sia necessario qui, tuttavia è un trucco preferito del < php 5,3 giorni, e lo sto rispettando (almeno fino a quando non comprenderò pienamente come funziona la garbage collection in php;).
Per qualcosa di più, devi davvero darci le specifiche dei tuoi calcoli e mostrarci il tuo codice.