26. May 2011 06:05
Keine Kommentare

PHP Performance Tuning

Erst kürzlich habe ich meinen Blog von WordPress befreit und die Software komplett neu entwickelt. Der Hauptgrund war, dass WordPress an sich - also dessen PHP Quellcode - sowie die MySQL Datenbank von WordPress alles andere als Performance optimiert sind. Ich wollte, dass mein Blog insbesondere hinsichtlich Suchmaschinenoptimierung die schnellstmögliche Ladezeit bietet und nicht wesentlich länger braucht als statische HTML Seiten. Soweit ist es mir, denke ich, auch sehr gut gelungen. In diesem Artikel beschreibe ich, was man beim Applikations- und Datenbankdesign mit PHP und MySQL beachten sollte, um eine schnelle Verarbeitung und sehr gute Performance garantieren zu können.

42,00 €
Jetzt bestellen »
High Performance MySQL. Optimierung, Datensicherung, Replikation & Lastverteilung
Gewöhnlich versandfertig in 24 Stunden

Effektives Datenbankdesign mit Views und Stored Procedures

Einige Leser werden mir vielleicht widersprechen, aber Datenbankgurus mit denen ich sprach stimmten mir zu: komplexe SQL Statements haben in PHP Applikationen nichts zu suchen. Zum Einen sind diese anfällig gegen SQL Injection und zum anderen rauben Sie der Datenbank die Möglichkeit die Performance zu optimieren.

Das Buch "High Performance MySQL", welches ich nur empfehlen kann, fordert dazu auf komplexe Abfragen in Views zu verpacken, sodass darauf einfach SELECT Statements durchgeführt werden. MySQL hat dann die Möglichkeit entsprechend seinen Cache aufzubauen und zu optimieren. Allein diese Tatsache beschleunigt den Vorgang ungemein, da die PHP Anwendung keine JOINs mehr durchführt, sondern diese direkt auf der Datenbank geschehen und MySQL dann Caching und Index-Optimierung durchführen kann. Die Architektur meines Blogs sieht demnach wie folgt aus.

Datenbank-Design des Kammerath Network

Wie hier klar zu sehen ist gibt es für jede Frontend-Ansicht, also jedes Statement, welches die PHP Anwendung durchführen wird eine View, welche die Daten bereits aufbereitet. Alle INSERT, UPDATE oder DELETE Operationen werden durch Stored Procedures abgebildet. Die Procedures, welche "ADD" vorangestellt haben, sind für INSERT und UPDATE zuständig. Wird zum Beispiel ein Artikel per "ADD" eingefügt, den es bereits gibt, so macht das Procedure natürlich ein UPDATE. Der Vorteil dieser Implementierung ist neben des verbesserten Schutzes gegen SQL Injection auch die verbesserte Wartbarkeit der Anwendung durch die Isolierung der Datenbanktabellen von der Applikation. Wird die Datenbank erweitert oder umgestellt, muss die PHP Anwendung nicht zwangsläufig angepasst werden, sondern lediglich die Stored Procedures und die Views.

Aus Sicht der Datenbank oder eines Datenbankentwicklers ist das eine sehr gute Angelegenheit, denn man möchte nicht, dass eine Webanwendung sich um die Datenintegrität oder Performance des Datenbankmanagementsystems kümmert. Vom Standpunkt des PHP Entwicklers aus, ist dies zudem noch angenehmer, da nicht tonnenweise SQL Code mit PHP Code vermischt wird, sondern lediglich Stored Procedures und Views aufgerufen bzw. abgefragt werden. Ein anschauliches Beispiel bietet der folgende Code.

Hierbei sieht man, dass lediglich ein sehr simples SELECT statement auf die View "article_list" durchgeführt wird, was die Methode hier in der Klasse "database" sehr schlank macht. Schauen wir uns nun einmal das dahinterliegende SQL der View an.

Hier sehen wir, dass ein JOIN der Tabelle "article" und "user" durchgeführt wird. Dabei muss man jetzt im Hinterkopf behalten, dass JOIN Operation das wohl intensivste Verfahren auf einer Datenbank ist. Wir haben hier im Quelltext nicht nur unseren PHP Code verschlankt sondern geben MySQL auch die Chance die Daten im Cache zu halten und nicht jedes Mal auf ein Neues einen JOIN durchführen zu müssen. Der Performance-Zuwachs durch solche einfachen Dinge ist enorm.

Selbiges gilt natürlich dann insbesondere für komplexere Abfragen wie z.B. Suchalghoritmen, mit welchen man in der Datenbank z.B. Textsuchen durchführen. Dies ist im Falle meines Blogs die Suchfunktion, mit welcher der Benutzer Artikel suchen kann. Da möchte man natürlich nicht nur eine lapidare WHERE Kondition verwenden, sondern natürlich auch die Häufigkeit des Vorkommens berücksichtigen. Das Stored Procedure sieht entsprechend wie folgt aus.

In diesem Beispiel sehen wir ein ziemliches Abfrage-Monster. Niemand möchte eine solche Monster-Funktion in seienm PHP Quelltext sehen. Der entsprechende PHP Quelltext hat hier auch nur eine Zeile, nämlich den Aufruf der Stored Procedure. Der Ansatz bei diesem Procedure war, dass die PHP Anwendung einfach nur den Suchbegriff angibt und die Datenbank selbstständig sucht und dann das Ergebnis zurückliefert. Das ist meines Erachtens nach eine der sinnvollsten Implementierungen von Stored Procedures. Wer sich das Procedure jetzt noch etwas genauer ansieht und diesen Artikel richtig gelesen hat, wird auch feststellen, dass die Abfrage der Suchfunktion ebenfalls auf einer View durchgeführt wird. Die tatsächliche Abfrage ohne Procedures und Views wäre also gut und gerne zwei A4 Seiten lang. Was das zusätzlich auf der Netzwerkschnittstelle bedeutet, wird wohl jedem klar. Statt hier jedes Mal unnötige Bytes hin- und her zu schieben belassen wir es bei dem Suchbegriff und der Rest ist auf der Datenbank vorbereitet, MySQL kann die Abfragen zudem selbst optimieren und weiß im Voraus, welche Abfragen Ihn erwarten.

PHP Performance Tuning durch Caching

Eine weitere sehr gute Maßnahme, um die Performance zu steigern, ist der Einsatz von Caching - also dem Zwischenspeichern von Information, sodass diese nicht jedes Mal von einer langsameren Quelle abgeholt werden müssen. Ein gutes Beispiel hier in meinem Blog sind die alternativen Artikelvorschläge (siehe dazu Google Analytics API für Amazon-ähnliche Vorschläge). Hierbei wird über die Google Analytics API abgefragt, welche Artikel andere Nutzer sonst noch gelesen haben, die sich für den Artikel interessieren, den der Nutzer sich gerade ansieht. Solche Berichte dauern recht lange und würden die Ladezeit unnötig verlangsamen. Zeitgleich ist es nicht notwendig die Daten mehr als 1x pro Tag von Google Analytics abzufragen, da diese dort auch nicht häufiger aktualisiert werden. Es macht also Sinn die Informationen zu cachen, was nachfolgende Klasse anbietet.

In diesem Fall verwendet die Klasse die Festplatte als Cache, da dies hier die beste Möglichkeit war. Ein Memcached-Server steht nicht zur Verfügung und wir möchten wir hier die Datenbank nicht weiter durch etwaige Memory-Tables belasten, zumal wir dann auch über die Netzwerkschnittstelle gehen müssen. In virtualisierten Umgebungen ist die Festplatte dann teilweise sowieso im RAM und damit hätten wir dann auch RAM-Caching, was PHP im Vergleich zu ASP.NET auf dem Microsoft Internet Information Server nicht direkt mitliefert. Die entsprechende Methode "getRecommendations" in einer anderen Klasse lädt die Berichtsdaten von Google Analytics und darum haben wir nun eine Methode "getCachedRecommendations" gebaut, welche den Cache verwendet und wie folgt aussieht.

Anzumerken sei hier der zweite Parameter der Methode, welcher es erlaubt einen vorzeitigen Refresh der Datei im Cache durchzuführen. Dieser Parameter wird von einem Script verwendet, welches als Cronjob läuft und zweimal täglich im Hintergrund den Cache erneuert, sodass wir verhindern, dass ein Besucher der gerade nach dem Auslaufen des Caches eine Seite aufruft eine langsamere Ladezeit erfährt. Dieses Verfahren ist auch häufig als sog. "Warmup" bekannt - also das Aufwärmen der Anwendung.

Client-seitige Performance-Optimierung

Es hilft nichts, wenn man ein enorm schnelles Backend hat und das Frontend durch diverse Unsinnigkeiten extrem langsam wird. Insbesondere Werbebanner sind gerne ein Kandidat dafür; in meinem Blog hier funktioniert das z.B. so, dass die Banner am Ende der Seite geladen werden und dann als absolutes DIV auf die gewünschte Position gebracht werden und das schlägt bei den Ladezeiten richtig gut zu Buche. Die wichtigsten Tipps zur Ladezeit-Optimierung am Frontend hat Yahoo zusammengestellt: Best Practices for Speeding Up Your Website.

19,62 €
Jetzt bestellen »
Even Faster Web Sites: Performance Best Practices for Web Developers
Versandfertig in 1 - 2 Werktagen

Ganz zum Schluss möchte ich noch erwähnen, dass der gezeigte Code unter der MPL 1.1 veröffentlicht wurde und der vollständige Code deshalb Open Source und als Kammerath Network Website System bei Google Project Hosting zur Verfügung steht. Des Weiteren freue ich mich immer sehr über Kritik, Fragen und Anregungen die gerne als E-Mail oder Kommentar kommen dürfen!

Bücher zum Thema „php“

Die nachfolgenden Bücher behandeln das Thema "php" und werden von Amazon empfohlen. Viele dieser Bücher habe ich selbst gelesen und teilweise auch zur Recherche für diesen Artikel genutzt.
19,90 €
Jetzt bestellen »
PHP 5.5 und MySQL 5.6: Ihr praktischer Einstieg in die Programmierung dynamischer Websites
Florence Maurice, dpunkt.verlag GmbH
19,90 €
Jetzt bestellen »
Einstieg in PHP 5.6 und MySQL 5.6 (Galileo Computing)
Thomas Theis, Galileo Computing
19,90 €
Jetzt bestellen »
Einstieg in PHP 5.5 und MySQL 5.6: Für Programmieranfänger geeignet (Galileo Computing)
Thomas Theis, Galileo Computing
4,14 €
Jetzt bestellen »
PHP Einsteigerkurs: Grundlagen der PHP/MySQL Programmierung in 5 Tagen verstehen
Klaus Thenmayer, CreateSpace Independent Publishing Platform

Diese Artikel könnten Dich auch interessieren

Besucher, die diesen Beitrag gelesen haben, haben sich auch die unten aufgeführten Beiträge angesehen. Schau' doch einfach mal in die Artikel rein.
10 Besucher haben auch das gelesen
9 Besucher haben auch das gelesen
7 Besucher haben auch das gelesen
6 Besucher haben auch das gelesen
5 Besucher haben auch das gelesen
5 Besucher haben auch das gelesen

Kommentare zum Thema „PHP Performance Tuning“

Wenn Du möchtest, kannst Du hier Kommentare zum Thema hinterlassen und Dich mit anderen Nutzern austauschen. Damit Du kommentieren kannst, musst Du Dich nur anmelden und schon kann es losgehen.
Jetzt zum Kommentieren anmelden