2009-03-23 9 views
6

Ho un'applicazione web PHP in cui alcuni dati cambiano su base settimanale ma vengono letti molto spesso.La migliore tecnica per memorizzare i risultati nella cache da query che cambiano raramente

Le query SQL che recuperano i dati e il codice php per l'output html sono piuttosto complessi. Ci sono più join di tabelle e numerosi calcoli, ma risultano in una tabella html abbastanza semplice. Gli utenti sono raggruppati e la tabella è la stessa per ogni gruppo ogni settimana, ma diversa per i diversi gruppi. Potrei potenzialmente avere centinaia di tabelle per migliaia di utenti.

Per motivi di prestazioni, mi piacerebbe memorizzare questi dati in cache. Piuttosto che eseguire queste query e calcoli ogni volta che qualcuno colpisce la pagina, voglio eseguire un processo settimanale per generare la tabella per ogni gruppo dandomi una semplice lettura quando richiesto.

Sarei interessato a sapere quali tecniche sono state utilizzate con successo o senza successo per ottenere qualcosa di simile?

Opzioni posso vedere includono:

  • memorizzare il risultato html dei calcoli in una tabella MySQL, identificato dal gruppo di utenti
  • memorizzazione dei dati risultanti in una tabella MySQL, identificati da gruppo di utenti (difficile come non c'è un numero fisso di elementi di dati)
  • Caching l'output della pagina in file statici

altri suggerimenti sarebbe il benvenuto!

risposta

4

Ci sono davvero poche opzioni:

  • Prerender le pagine su base settimanale e poi servire "staticamente".
  • Utilizzare una cache (ad esempio Squid) per memorizzare tali risposte in una prima volta per una settimana. Ad esempio, è possibile configurare la politica di memorizzazione nella cache in modo che le richieste che vanno a una particolare pagina (ad esempio very_long.php? ...) siano memorizzate nella cache separatamente dal resto del sito.
  • Assicurarsi di attivare la memorizzazione nella cache di DB. MySQL ha il proprio caching e si può mettere a punto in modo che le query lunghe ripetute non vengano ricalcolate.
+0

Alcuni ottimi suggerimenti, grazie. – Damovisa

+0

Buona lista di suggerimenti qui. Si noti che il caching delle query MySQL non è una soluzione completa, ma presenta vantaggi e svantaggi (può peggiorare i dati aggiornati di frequente). Come suggerito da Assaf, è solo una delle molte opzioni. – thomasrutter

2

prima di tutto profilo. verificare che tali query consumino effettivamente una quantità significativa di tempo. forse le cache dei risultati delle query MySQL hanno già svolto il lavoro per te.

se realmente consumano risorse, quello che vorrei fare è creare una tabella con i risultati calcolati, e una procedura che faccia tutto il necessario per la gestione, da chiamare quando i dati cambiano. quelle letture frequenti dovrebbero andare solo ai dati pre-calcolati, senza preoccuparsi di verificare se è ancora valido.

aggiungere semplicemente alcuni aggancio alle procedure che modificano i dati di base o trigger di database, se possibile, questi potrebbero essere eseguiti in modo non frequente (settimanale?) E potrebbero richiedere molto tempo per generare risultati.

+0

Penso che questa sia la prima volta che vedo una domanda che ha quattro risposte e sono tutte buone (meritano tutti un voto positivo)! Buoni suggerimenti qui. Il bisogno di profilare prima di ottimizzare è un buon punto. – thomasrutter

+0

Vero - Sono rimasto molto colpito! – Damovisa

6

Nella funzione per generare la tabella, fanno memorizzare il risultato a un file su disco:

/cache/groups/1.txt 
/cache/groups/2.txt 

Non dovete necessariamente eseguire un processo batch settimanale per esso, quando si chiama la funzione di ottenere i dati, controllare se la cache non è aggiornata (o inesistente).In tal caso, generare e memorizzare i risultati successivamente. In caso contrario, è sufficiente restituire il file memorizzato nella cache.

function getGroupTable($groupId) { 
    if (cacheIsStale($groupId)) { 
     generateCache($groupId); 
    } 
    return file_get_contents($cacheFile); 
} 

La funzione cacheIsStale() potrebbe basta guardare il file's timestamps per verificare la freschezza.

+0

Questo è il modo in cui ho gestito questo problema molto tempo fa. –

+0

È una buona soluzione e probabilmente una che userò. Sono solo preoccupato del potenziale (futuro) necessità di utilizzare i dati generati anziché solo l'html. – Damovisa

+0

in questo caso, potresti forse archiviare i risultati di MySQL in un formato diverso e più accessibile. CSV funzionerebbe facilmente (la funzione fgetcsv aiuta qui), o potresti persino inserire il risultato in un array e poi serializzarlo. Certo, potresti fare due file di cache: HTML e dati grezzi. – nickf

2

Sembra che ne abbiate già coperto gran parte.

Un altra opzione, assumendo i dati della tabella non è enorme, è quello di utilizzare memcache per mettere in cache i risultati - questa sarebbe probabilmente la soluzione più veloce, anche se avrebbe bisogno di controllare i requisiti di memoria per vedere se si tratta di una valida opzione.

Problemi correlati