Sven Rautenberg: Performance: include vs. MySQL

Beitrag lesen

Moin!

Trotzdem bleibt bei mir eine (grosse) Unklarheit:

Eine schnelle DB-Abfrage, die ermittelt, ob mehrere umfangreiche DB-Abfragen nötig sind

Wie stell ich das fest? Habe keinerlei Erfahrung auf dem Gebiet, Hilfestellung waere sinnvoll.
Und wie kann ein php-Script erkennen, dass es sich selbst "gecachten" soll, also keine neuen DB-Daten anbietet, weil die Datenbank noch immer auf dem alten Stand ist? Waere da meine Vorgehensweise, nur DB-Kontakt herzustellen, wenns noetig ist, und sonst die erstelle HTML-Datei includen, im Ansatz richtig/ in Ordnung?

Beim Caching ist folgendes Muster typisch:

Der tatsächliche Aufruf ruft nicht mehr stur direkt die aufwendige Berechnungsaktion auf, sondern prüft zunächst mal, ob dafür überhaupt ein Anlass besteht. Dazu muss in irgendeiner Weise der Zustand "Cache ist veraltet, muss neu" ermittelt werden. Und diese Operation, zusammen mit dem Auslesen aus dem Cache, ist nicht unbedingt einfacher bzw. schneller. Je nach Häufigkeit der Cache-Aktualisierung kommt auch das Neuschreiben des Caches als Zeitfaktor hinzu.

Nur mal so als Rechenbeispiel: Wenn die normale Operation 10 Zeiteinheiten benötigt, das Ermitteln des Cache-Inhalts 2 Zeiteinheiten, das Auslesen des Caches ebenfalls 2 Zeiteinheiten, und das Neuschreiben des veralteten Caches 5 Zeiteinheiten, dann hast du folgende Muster:

Normalzustand ohne Caching: 10
Cache-Miss: 2 + 10 + 5 = 17 (Cachezustand ermitteln, die eigentliche Operation voll durchführen, und in Cache speichern)
Cache-Hit: 2 + 2 = 4 (Cachezustand ermitteln und auslesen)

Hundert Aufrufe ohne Caching:
100 * 10 Zeiteinheiten ohne Cache = 1000 Einheiten

Wenn viele hundert Lesevorgänge den Cache nutzen, ist Caching in DIESER Zeitverteilung vorteilhaft:
99 * 4 Zeiteinheiten mit Cache + 1 * 17 Einheiten ohne Cache = 413 Einheiten

Wenn hingegen die Hit- und Miss-Vorgänge 50:50 verteilt sind, weil sich Dinge schnell ändern, sieht es nicht gut aus:
50 * 17 Einheiten (Cache neu füllen) + 50 * 4 Einheiten (Cache lesen) = 1050 Einheiten

Das ist langsamer, als die Originalen 1000 Einheiten ohne Caching. :)

Der Mysql-Query-Cache beispielsweise sitzt vorteilhaft direkt an der Quelle, und kann Veränderungen an der Tabelle, die im Cache steckt, direkt kontrollieren: Schreibzugriffe auf die Tabelle invalidieren den Cache automatisch.

Dummerweise ist der Cache ein ziemlich dummer: Wenn dein Query nicht aufs Zeichen genau vorher schon einmal erfolgte, oder wenn das Ergebnis aufgrund von dynamischen Funktionen ermittelt wird, wie z.B. NOW() (die aktuelle Uhrzeit ändert sich jede Sekunde, das Query-Ergebnis deshalb potentiell auch), kann MySQL nichts cachen. Da muss man also durch Messen und Erfahrungswerte seine Querys so optimieren, dass man in den Genuss des Caches kommt.

- Sven Rautenberg