2009-03-23 15 views
6

Ich habe eine PHP-Webanwendung, in der bestimmte Daten wöchentlich geändert werden, aber häufig gelesen werden.Beste Technik zum Zwischenspeichern von Ergebnissen aus selten wechselnden Abfragen

Die SQL-Abfragen, die die Daten und den PHP-Code für die HTML-Ausgabe abrufen, sind ziemlich komplex. Es gibt mehrere Tabellen-Joins und zahlreiche Berechnungen - aber sie ergeben eine recht einfache HTML-Tabelle. Benutzer werden gruppiert, und die Tabelle ist für jede Gruppe jede Woche gleich, aber für verschiedene Gruppen unterschiedlich. Ich könnte potenziell Hunderte von Tabellen für Tausende von Benutzern haben.

Aus Leistungsgründen möchte ich diese Daten zwischenspeichern. Anstatt diese Abfragen und Berechnungen jedes Mal auszuführen, wenn jemand auf die Seite klickt, möchte ich einen wöchentlichen Prozess ausführen, um die Tabelle für jede Gruppe zu generieren, die mir bei Bedarf einen einfachen Lesevorgang ermöglicht.

Ich würde gerne wissen, welche Techniken Sie erfolgreich oder ohne Erfolg verwendet haben, um so etwas zu erreichen?

Optionen kann ich sehen, umfassen:

  • das HTML-Ergebnis der Berechnungen in einer MySQL Tabelle gespeichert, die von Benutzergruppe
  • die resultierenden Daten in einer MySQL Tabelle gespeichert, die von Benutzergruppe identifiziert (schwer da es keine feste Anzahl von Datenelementen ist)

Alle anderen Vorschläge willkommen wäre, die Seitenausgabe in statischen Dateien Caching!

Antwort

4

Es gibt in der Tat ein paar Optionen:

  • Prerender die Seiten auf einer wöchentlichen Basis und sie dann „statisch“ dienen.
  • Verwenden Sie einen Cache (z. B. Squid), um solche Antworten für eine Woche auf einer ersten Chance zu cachen. Beispielsweise können Sie die Caching-Richtlinie so konfigurieren, dass Anforderungen, die zu einer bestimmten Seite gehen (z. B. very_long.php? ...), separat vom Rest der Website zwischengespeichert werden.
  • Stellen Sie sicher, dass Sie das DB-Caching aktivieren. MySQL hat ein eigenes Caching und Sie können es so einstellen, dass wiederholte lange Abfragen nicht neu berechnet werden.
+0

Einige gute Vorschläge, danke. – Damovisa

+0

Gute Liste von Vorschlägen hier. Beachten Sie, dass das MySQL-Query-Caching kein vollständiger Fix ist - es hat Vor- und Nachteile (es kann bei häufig aktualisierten Daten die Situation verschlimmern). Wie von Assaf vorgeschlagen, ist dies nur eine von vielen Optionen. – thomasrutter

2

vor allem, Profil. Überprüfen Sie, ob diese Abfragen wirklich viel Zeit in Anspruch nehmen. Vielleicht hat MySQL Query Result Caches bereits die Arbeit für Sie erledigt.

Wenn sie wirklich Ressourcen verbrauchen, was ich tun würde, ist eine Tabelle mit den berechneten Ergebnissen zu erstellen, und eine Prozedur, die alle erforderlichen verwalten, um bei Änderungen der Daten aufgerufen werden. Diese häufigen Lesevorgänge sollten nur zu den vorberechneten Daten gehen, ohne sich zu vergewissern, ob sie noch gültig sind.

fügen Sie einfach einige Hooks zu den Prozeduren hinzu, die die Basisdaten modifizieren, oder Datenbanktrigger, wenn Sie können, diese würden selten (wöchentlich?) Ausgeführt werden und könnten viel Zeit brauchen, um Ergebnisse zu generieren.

+0

Ich denke, das ist das erste Mal, dass ich gesehen habe, wo eine Frage vier Antworten hat, und sie sind alle gut (alle verdienen eine höhere Bewertung)! Gute Vorschläge hier. Die Notwendigkeit, vor der Optimierung zu profilieren, ist ein guter Punkt. – thomasrutter

+0

Stimmt - ich war ziemlich beeindruckt! – Damovisa

6

In der Funktion, die Tabelle zu erzeugen, ist es das Ergebnis in eine Datei auf der Festplatte speichern machen:

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

Sie müssen nicht unbedingt einen wöchentlichen Batch-Job für sie ausführen müssen, beim Aufruf der Funktion Holen Sie die Daten, prüfen Sie, ob der Cache veraltet ist (oder nicht vorhanden ist).Wenn ja, generieren und cachen Sie die Ergebnisse dann. Wenn nicht, gib einfach die zwischengespeicherte Datei zurück.

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

Die cacheIsStale() Funktion konnte nur Blick auf die file's timestamps für Frische zu testen.

+0

So habe ich vor langer Zeit ein solches Problem behandelt. –

+0

Es ist eine gute Lösung und wahrscheinlich eine, die ich verwenden werde. Ich bin nur mit dem potenziellen (zukünftigen) Bedürfnis beschäftigt, die erzeugten Daten anstatt nur den HTML zu verwenden. – Damovisa

+0

In diesem Fall könnten Sie die Ergebnisse von MySQL möglicherweise in einem anderen, besser zugänglichen Format speichern. CSV würde einfach funktionieren (die Funktion fgetcsv hilft hier), oder Sie könnten das Ergebnis sogar in ein Array einfügen und es dann serialisieren. Natürlich könnten Sie zwei Cache-Dateien erstellen: HTML- und Rohdaten. – nickf

2

Es scheint, dass Sie bereits das meiste davon abgedeckt haben. Eine andere Möglichkeit, die Tabellendaten nicht groß zu verwenden, ist memcache zu verwenden, um die Ergebnisse zwischenzuspeichern - dies wäre wahrscheinlich die schnellere Lösung, obwohl Sie Speicheranforderungen überprüfen müssten, um zu sehen, ob es eine praktikable Option ist.

Verwandte Themen