Moin!
Bei meinem kleinen PHP-Framework kommt mittlerweile das Problem auf, dass ich bei jedem Seitenaufruf größere Datenmengen aus MySQL Datenbanken auslesen muss.
Du meinst kleinere Datenmengen.
Damit das alles so fix wie möglich abläuft hab ich mir vorgestellt die Ergebnisse dieser Abfragen zu cachen.
Hast du gemessen, wie lange ein Seitenaufruf insgesamt, und detailliert je Datenbankabfrage zeitlich braucht? Tu das. Denn nur mit diesen Messergebnissen (gemittelt über mehrere einzelne Seitenaufrufe) weißt du, wann sich durch Änderung was verbessert.
Die Frage ist nun, welche Methode am besten ist.
MySQL hat einen schönen Query-Cache. Die exakt gleiche Anfrage wird also beim zweiten Mal schon aus dem Cache beantwortet, sofern es sich um eine statische Anfrage handelt. Bestandteile wie "NOW()" sind nicht statisch und deshalb nicht cachebar.
Situation:
Ich habe eine MySQL-Tabelle "Module" mit den Feldern name (primary key), title, description, status und noch ein paar mehr.
Es werden sich wohl ca. 50-200 Datensätze in der Tabelle befinden.
Peanuts. Dafür baut man sich keinen Extra-Cache.
Bei jedem Seitenaufruf benötige ich die Daten von geschätzten 10-20% der vorhandenen Module (immer unterschiedliche).
Also 5 bis 40 Datensätze? Peanuts. Dafür baut man sich keinen Cache.
Mir fallen jetzt folgende Möglichkeiten ein diese Daten abzufragen:
- Ich frage jedes benötigte Modul einzeln ab und erstelle mithilfe der Daten der Abfrage das passende PHP-Objekt.
"Separation of concern" ist definitiv die Methode, die man in OOP haben will.
Allerdings fasst du die Sache vermutlich von der falschen Seite an, denn das Objekt erstellt sich selbst, indem es ggf. die Datenbank befragt - es wird nicht mit den Infos aus der Datenbank manuell befüllt.
- Ich frage bei jedem Seitenaufruf alle Datensätze ab, erstelle in einer schleife alle PHP-Objekte und speichere diese in einem Array, auf welches ich dann zugreife wenn ein konkretes Modul benötigt wird.
Negativ. Du instanziierst ein Objekt genau dann, wenn du es benötigst, und fragst erst genau dann die dazu gehörenden Daten ab.
3a. Ich speichere die einzelnen Module aus 1. in serialisierter Form in einer MySQL-Tabelle (Config), welche ich sowieso bei jedem Aufruf vollständig lade) und greife dann bei Bedarf auf diese Daten zurück.
wenn ein Modul geändert wird, wird der dazugehörige Config-Eintrag neu erstellt.
3b. wie 3a, allerdings speichere ich den in 2. gespeicherten Array mit allen Modulen in serialisierter Form in der Config-Tabelle und wandle diesen dann bei jedem Seitenaufruf zurück in einen Array, auf den ich dann bei Bedarf zugreifen kann.
Wenn ein Modul geändert wird bzw ein neues hinzukommt, wird der DB-Eintrag komplett neu erstellt.
4a. wie 3a, aber die Serialisierten Module werden nicht in der DB, sondern in (jeweils einer eigenen) Datei gespeichert.4b. wie 3b, aber das Array wird in einer Datei gespeichert.
Serialisierte Objekte bringen dir lediglich eine zusätzlichen Schicht Komplexität ins Spiel, die du nach meinem Eindruck noch nicht handhaben kannst, und die dir absolut nichts bringt.
Noch zu erwähnen wäre, dass es neben der Modul-Tabelle noch weitere Objekte gibt, mit denen ich ähnlich verfahren wollte.
Da ich das Framework auf verschiedenen Systemen nutzen wollte kann ich zu verwendeter Hardware bzw PHP/MySQL-Konfiguration leider nichts sagen (sofern die PHP-Einstellungen sich nicht im PHP-Code selbst ändern lassen).
Ich bin ja schon zitiert worden, und es ist wahr: Du hast, rein von der Datenmenge her, absolut keinen Grund, schon irgendwelches Tuning mit Caches anzuwenden. Wenn du das jetzt schon als notwendig erachtest, ist dein Design sehr kaputt.
Und vermutlich hast du bis jetzt auch keinen Überblick, wo dein angebliches Performanceproblem denn wirklich seine Ursache hat, weil dir keine harten Fakten zum Zeitverhalten deiner Skripte vorliegen.
Ändere das! microtime(true) liefert dir eine schöne, hochaufgelöste Zeitangabe in eine Variable. Du kannst aber natürlich auch das xdebug-Modul zum Profiling einsetzen und mit kcachegrind nachgucken, was dein Code wie lange und wie häufig tut.
- Sven Rautenberg