Schon seit einiger Zeit fiel mir auf, dass die Ladedauer meines Blogs extrem hoch war. Messungen zeigten, dass allein das Laden der Startseite (ohne darin enthaltene Grafiken, Stylesheets o.ä.) fast 3 Sekunden dauerte. Dass der Serendipity-Code aufgrund schlechter Programmierung die Ursache ist, konnte ich mir kaum vorstellen. Deshalb habe ich einmal die Datenbank-Queries untersucht, die dabei immer ausgeführt werden. Dabei hat sich dann herausgestellt, dass die Queries des Statistik-Plugins (serendipity_event_statistics) keine Indizes verwenden. Da die betreffenden Tabellen im Laufe der Zeit aber Millionen von Einträgen enthalten, dauert es natürlich entsprechend lang, diese alle zu durchsuchen. Folglich verzögert dies die Ausführung des PHP-Skripts enorm.
Montag, 11. Juli 2011
Das Statistik-Plugin von Serendipity als Performance-Killer
Auf der Suche nach möglichen Lösungen habe ich deshalb testweise geeignete Indizes erstellt, was sofort zu einer enormen Performance-Steigerung führte. Da ich das Plugin an sich eigentlich sowieso nicht benötige, habe ich es zudem auch noch deaktiviert, was logischerweise noch bessere Werte lieferte.
Da es sich leider um ein Core-Plugin handelt, kann ich dieses leider nicht selbst in Bezug auf die Verwendung von Indizes anpassen. Ich werde meine Optimierungsvorschläge jedoch an die Entwickler weiterleiten, damit diese hoffentlich ich das nächste Release einfließen.
Wer nicht so lange warten will und das Plugin trotzdem verwenden möchte, sollte daher selbst die erforderlichen Indizes erzeugen. Dazu sind folgende MySQL-Befehle auszuführen ("blog_" dabei durch eigenes DB-Prefix ersetzen!):
ALTER TABLE blog_visitors_count ADD KEY `year_month_day`(`year`, `month`, `day`);
ALTER TABLE blog_visitors ADD KEY `sessID`(`sessID`);
ALTER TABLE blog_visitors ADD KEY `day`(`day`);
ALTER TABLE blog_visitors ADD KEY `ip`(`ip`);
Um Datenbank-Probleme beim Update auf die nächste Serendipity-Version zu vermeiden, ist zu empfehlen, die Indizes davor temporär zu entfernen. Sofern dieses Update die Anpassungen bezüglich der Indizes enthält, werden diese dann sowieso automatisch angelegt. Andernfalls lassen sich diese dann ja auch leicht von Hand wieder erstellen.
Die mit dieser Anpassung erzielte Verbesserung lässt sich sehr deutlich an der resultierenden Ladedauer der Startseite erkennen. Bei meinen Tests konnte ich folgende Werte erreichen:
Statistik-Plugin aktiv? | Indizes vorhanden? | Ladedauer |
---|---|---|
ja | nein | 2,7s |
ja | ja | 0,8s |
nein | nein | 0,3s |
nein | ja | 0,3s |
Da sich das Plugin scheinbar an einigen Stellen einklinkt, wirkt es sich natürlich nicht nur beim Anzeigen von Artikeln oder der Startseite aus. Beispielsweise konnte ich noch feststellen, dass das Speichern von Artikeln wesentlich schneller geht.
Somit ist davon auszugehen, dass es sicher noch einige weitere Optimierungsmöglichkeiten gibt. Gerne können mir diese über Kommentare oder Mails mitgeteilt werden, so dass ich diesen Eintrag noch entsprechend erweitern kann.
Update 18.07.2011:
Als ich einen Patch für das Statistik-Plugin erstellen wollte, hat sich herausgestellt, dass dieses eigentlich doch Indizes erstellt. Sofern diese fehlen, müssten diese bei jedem Update eigentlich wieder erstellt werden. Dies scheint jedoch aus unerfindlichen Gründen bei meinem Blog nicht funktioniert zu haben.
Um wieder ein korrektes Datenbank-Schema zu erhalten, habe ich die fehlenden Indizes daher manuell erstellt. Folgende MySQL-Befehle ("blog_" dabei wieder durch eigenes DB-Prefix ersetzen!) müssen dazu ausgeführt werden:
CREATE INDEX visitorses ON blog_visitors (`sessID`);
CREATE INDEX visitorday ON blog_visitors (`day`);
CREATE INDEX visitortime ON blog_visitors (`time`);
CREATE INDEX visitortimeb ON blog_visitors_count (`year`, `month`, `day`);
CREATE INDEX refsrefs ON blog_refs (`refs`);
CREATE INDEX refscount ON blog_refs (`count`);
Bitte unbedingt an Garvin und Co. weiterleiten. Das ist wohl eine wichtige Info.