Für Menschen · Seien Sie begeistert und Sie werden begeistern !
Die Performance von WordPress kann schnell und einfach mittels einiger Plugins verschlechtert werden. Dazu muss man kein Experte sein, mehr Funktionalität sorgt für mehr Last. Allerdings sorgt gerade die Einfachheit und offene Arbeitsweise von WordPress, die WordPress unter anderem so populär gemacht haben und ich sehr schätze, zu einem Problem - das Plugin muss nicht unbedingt von Profi-Entwicklern erstellt sein und die Optimierung des Syntax würde viel im Bereich Performance verbessern.
Nun aber zum eigentlichen Problem: wie findet man die Schwachstelle im Blog?
Einerseits kann mittels weniger Tools die Performance analysieren, dazu dient mir beispielsweise das Add on Firebug im Browser Firefox. Damit sind schnell große Scripte gefunden und Schwachstellen im Code. Dazu auch der Hinweis auf den Artikel „Ladezeiten bei WordPress-Templates optimieren“. Sinnvoll ist ebenfalls, die „vielen“ Scripte, die einige Plugins mitbringen, nicht per wp_head, sondern in wp_footer anzusteuern. Damit bleibt der Aufbau nicht an den Scripten hängen, die eventuell nur Mehrwert bieten. Ab in den Footer mit derartigen Scripten.
Allerdings ist die Analyse via Deaktivieren/ Aktivieren aller Plugins nach und nach mühsam. Da wäre es doch sinnvoll, man sucht die einzelnen Queries ab und schaut auf welche Funktion sie verweisen.
WordPress bietet von Hause aus die Möglichkeit, dass man sich die Gesamtzahl der Queries ausgeben lassen kann, ebenso die benötigte Zeit. Mit folgendem Syntax, vorzugsweise in den Footer der Seite gelegt, ist dies schnell geschehen.
<?php echo $wpdb->num_queries; ?>q, <?php timer_stop(1); ?>s
Aber die Variable $wpdb bietet mehr, dazu schaut man in die /wp-includes/wp-db.php.
if (!defined('SAVEQUERIES'))
define('SAVEQUERIES', false);
class wpdb {
var $show_errors = true;
var $num_queries = 0;
var $last_query;
var $col_info;
var $queries;
var $prefix = '';
// Our tables
var $posts;
var $users;
var $categories;
var $post2cat;
var $comments;
var $links;
var $options;
var $postmeta;
var $usermeta;
var $terms;
var $term_taxonomy;
var $term_relationships;
var $tables = array('users', 'usermeta', 'posts', 'categories', 'post2cat', 'comments', 'links', 'link2cat', 'options', 'postmeta', 'terms', 'term_taxonomy', 'term_relationships');
var $charset;
var $collate;
Dabei fällt die Konstante SAVEQUERIES auf, die im Standard nicht in der wp-config.php definiert ist. Setzt man diese Konstante auf TRUE, dann sind weitere Möglichkeiten offen.
Aber auch darauf will ich nicht im Detail eingehen, denn es würde zu weit führen, wer Interesse hat, der findet in der besagten Datei eine ganze Reihe von Infos.
Mein Ziel war es nun aber, dass man nicht die Gesamtzahl der Queries im Blog als Ergebnis bekommt, sondern die einzelnen Abfragen inklusive ihrer auszuführenden Syntax, denn so kann ich das Problem explizit im Code finden.
Damit die Arbeit einfach und schnell an dem jeweiligen Blog von der Hand geht, habe ich die Funktion in ein Plugin ausgelagert und aktiviere es nur, wenn ich auch eine Analyse durchführen möchte. Außerdem wird die Analyse nur gestartet und das Ergebnis ausgeben, wenn man als Administrator eingeloggt ist.
Das Ergebnis kann das beispielsweise folgendermaßen aussehen.

16. Time: 0.000431060791016
Query: SELECT object_id, term_taxonomy_id FROM fb122_term_relationships INNER JOIN fb122_posts ON object_id = ID WHERE term_taxonomy_id IN (6,5,1) AND post_type = 'post' AND post_status = 'publish'
Call from: wp-includes\taxonomy.php(2093): wpdb->get_results()
17. Time: 0.00243401527405
Query: SELECT t.*, tt.* FROM fb122_terms AS t INNER JOIN fb122_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ('link_category') AND tt.count > 0 ORDER BY t.name ASC
Call from: wp-includes\taxonomy.php(777): wpdb->get_results()
18. Time: 0.00080418586731
Query: SELECT * , IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated FROM fb122_links INNER JOIN fb122_term_relationships AS tr ON (fb122_links.link_id = tr.object_id) INNER JOIN fb122_term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id WHERE 1=1 AND link_visible = 'Y' AND ( tt.term_id = 2 ) AND taxonomy = 'link_category' ORDER BY link_name ASC
Call from: wp-includes\bookmark.php(255): wpdb->get_results()
* Total query time: 0.02111s for 18 queries.
* Page generated in 0.36373s, 94.20% PHP, 5.80% MySQL
Für den Laien ist damit die Arbeit sicher nicht unbedingt angenehm, aber so finde ich die eigentlichen Probleme in der Datenbankabfrage und kann die jeweilige Abfrage in den Dateien suchen und eventuell verbessern bzw. deaktivieren. Das Plugin bedient noch einige mehr Informationen als das obige Tutorial, so dass es verständlicher wird und mehr Informationen liefert.
Nach dem Aktivieren des Plugins werden die einzelnen Abfragen in den Footer der Seite geschrieben, als HTML-Kommentar, so dass man den Quelltext analysieren muss, um an die Werte zu kommen. Die Werte werden nur analysiert und ausgegeben, wenn man als Administrator im Blog eingeloggt ist.
Das Plugin benötigt WordPress Version 1.5 und wurde getestet bis Version 2.9-rare.
/wp-content/plugins/)Ist die Arbeit nicht 1 Euro wert?
Jede Spende wird dankbar angenommen und ermöglicht das weitere Arbeiten an freier Software.
Möchtest du mehr oder anders spenden, so besuche meine Wunschliste.

Download als zip-Datei:
downloads.wordpress.org/plugin/debug-queries.zip - 2 kByte
Ich bin urlaubsreif, ersticke in Arbeit und damit auch für die Leser des Weblogs nicht zu erreichen. Bitte geduldet euch ein wenig mit Supportanfragen.
Leider muss ich die Kommentarfunktion deaktivieren, ansonsten würde ich weiter in Arbeit ersticken oder die Anfragen nicht nach bestem Gewissen beantworten.
Vielen Dank für das Verständnis!
bueltge.de [by:ltge.de] wird von Frank Bültge geführt, administriert und gestaltet. Alle Inhalte sind persönlich von mir ausgewählt und erstellt, nach bestem Gewissen und Können, was die Möglichkeit von Fehlern nicht ausschließt.
Das Weblog wird angetrieben von WordPress und aktuell gibt es 854 Beiträge, 15036 Kommentare in 14 Kategorien und 450 Tags.
Das Blog wird liebevoll mit xHTML & CSS in Handarbeit gestaltet.
Design und Code ist unter Copyright
© 2001 - 2010 bueltge.de [by:ltge.de]
4. Dezember 2007 um 12:39
4. Dezember 2007 um 12:44
Das Plugin ist praktisch
Nur leider bekomme ich eine Error-message:
Invalid argument supplied for foreach() in *** L 17
Greetz Phil
4. Dezember 2007 um 12:58
wow - grosses kino mal wieder, funktioniert einwandfrei und hilft wirklich sehr. das ganze wird auch gleich an einige kunden empfohlen die sich über schlechte performance beschweren, aber nicht einsehen das viele informationen auch viele datenbankabfragen bedeutet.
danke für die arbeit!
4. Dezember 2007 um 14:29
@ Phil
Lies nochmal die Installationsanleitung, vor allem Punkt 3!
@Frank
Sehr nice, danke!
4. Dezember 2007 um 16:35
Das ist ja wieder einmal ein Highlight aus der Softwareschmiede Bültge
4. Dezember 2007 um 16:39
2 Autoren - ein Gedanke: Verwende SAVEQUERIES auch zur Optimierung und wollte es ebenfalls nach meinem Nachtschichtblock in ein Plugin packen, allerdings mit einem anderen Ansatz: Das Plugin schreibt nach Aktivierung einmalig die gesammelten Queries und Zeiten in eine Datenbanktabelle die dann im Adminmenü abgerufen werden kann, wobei die Queries zusätzlich noch mit einer EXPLAIN-Query verlinkt sein sollten. So könnte man dann einfach und gezielt nach Performanceproblemen forschen.
Naja, vielleicht schreibe ich es ja trotzdem noch…
Grüsse
4. Dezember 2007 um 21:17
Plug-In installiert und Auswertung im Quelltext angeschaut.
Zunächst musst ich mir die Augen reiben, ist ja doch sehr kryptisch.
Resultat: Total query time: 0.17107510566711
vermutlich ist das kein besonders guter Wert?
Da die Werte für wp_term_relationships und wp_term_taxonomy am höchsten waren habe ich mal nachgeforscht was sich dahinter verbirgt:
WP-Datenbank-Erklärungen
also irgendwas mit Kategorien-zuordnen.
Habe dann das Plug-In Advanced-Category-Excluder deaktiviert und konnte somit den Wert senken.
Resultat: Total query time: 0.073061466217041
Das sieht schon besser aus,
aber leider mag ich auf dieses Plug-In nicht verzichten.
4. Dezember 2007 um 21:28
4. Dezember 2007 um 22:58
Autsch...
Entschuldige ! Das passiert wenn man eifrig ans Werk gehen will weil einem das eigene System nervt und zum Stier macht *gg*
Danke für den blitz Tip
Greetz & gute Nacht, vile Glück
Phil
5. Dezember 2007 um 00:22
5. Dezember 2007 um 09:49
@ Phil
Mir ist das gleiche passiert!
5. Dezember 2007 um 09:49
wie immer sehr geiles Plugin. Werde es nachher mal testen.
Damit die Arbeit damit einfach und schnell an dem jeweiligen BlogHört sich irgendwie komisch an
5. Dezember 2007 um 12:12
@Nils: Danke! - klingt und ist komisch, gefixt.
6. Dezember 2007 um 15:34
ich bin selbst kein großer php und datenbank-typ. was sind denn gute werte? in deinem obige screenshot ist die Total query time 0.0315816402435 - bei meiner website spuckt das plugin Total query time: 0.021893262863159 aus. ist das jetzt gut? schlecht? gibt es im netzt einen artikel zu dem thema?
ansonsten respekt für eine wunderbare webseite.
6. Dezember 2007 um 15:46
Auch ich bin kein Experte für dieses Thema, aber entscheidend ist der Vergleich der ausgespuckten Werte. Im Vergleich zeigt sich, was dauert und wie lange. Damit kann man einigen Extremen auf den Grund gehen. Eventuell kann man sie nicht beseitigen, aber man kann entscheiden, ob man sie unbedingt benötigt, weil sie beispielsweise von einem Plugin kommen oder nicht.
Ansonsten hilft eventuell der Artikle "Using the New MySQL Query Profiler".
6. Dezember 2007 um 18:06
vielen lieben dank für deine antwort
9. Dezember 2007 um 13:23
Bei mir kommt die gleiche Fehlermeldung wie bei phil.
Ich habe savequeries auf "true" gesetzt und bin als admin angemeldet.
Trotzdem.
Irgendeine Idee?
10. Dezember 2007 um 12:14
12. Dezember 2007 um 15:37
Hallo!
Dieses Plugin hat mir gut dabei geholfen, die Performance aus Sicht des Users deutlich zu erhöhen..
Aber jetzt mein verbleibendes Wehwehchen: Die Ladezeiten im Adminbereich von WP sind abgrundtief schlecht.. wenn ich nur Spam löschen will, warte ich schon mal 1-2 Minütchen auf eine Reaktion - auch alle anderen Aktionen (aktivieren/deaktivieren v Plugins, Einfügen von Bannercode ins WPAds, ...) enden in ellenlangem Warten...
Weiß jemand Rat?
12. Dezember 2007 um 16:48
Eventuell ©Feed im Einsatz, dann schau die Kommentare zum Plugin an, dort ist die Lösung dazu.
Ansonsten schau mal, ob du ein Plugin im Einsatz hast, welches Daten von Außen holt, das ist dann das Problem. ©Feed macht das und wenn der Service nicht verfügbar ist, dann hackt es.
12. Dezember 2007 um 18:34
Ui, ngg gallery haut ganz schön:
9.3936920166016E-5 SELECT filename FROM wp_ngg_pictures WHERE pid = '71'
0.00024104118347168 SELECT path FROM wp_ngg_gallery WHERE gid = '4'
9.7036361694336E-5 SELECT galleryid FROM wp_ngg_pictures WHERE pid = '71'
9.1075897216797E-5 SELECT filename FROM wp_ngg_pictures WHERE pid = '71'
9.3936920166016E-5 SELECT path FROM wp_ngg_gallery WHERE gid = '4'
Total query time: 0.043978929519653
12. Dezember 2007 um 19:34
Da steht aber E-5, also 0,00009 !?
12. Dezember 2007 um 20:22
Vielen Dank für den Hinweis! das ganze Adminpaneel rennt wieder...
und @Nils: ebenso habe ich mich auch erschreckt - bis ich die "E-5" entdeckt habe
12. Dezember 2007 um 20:36
oh, ok, die habe ich dann übersehen ^^
22. Januar 2008 um 02:11
6. Februar 2008 um 18:54
12. Februar 2008 um 08:44
24. März 2008 um 12:39
Gut dass es sowas gibt. Ich bin dabei etwas neues mit WP zu realisieren und da muss unbedingt auf die performance achten. manchmal ist es doch besser plugin selber zu schreiben, wenn fertige plugins zu viel performance beanspruchen, obwohl man nur vlt. die hälfte der funktionen benötigt.
gruß
damian
7. Mai 2008 um 03:10
Hallo,
funktioniert das plugin auch unter wp 2.5.1 ?
lg
thomas
8. Mai 2008 um 19:43
@thomas: ja, sollte ohne Probleme laufen.
12. Mai 2008 um 10:39
23. Juni 2008 um 22:22
15. August 2008 um 23:54
Abend;
unter WP 2.6 läuft es leider nicht, könntest du da bitte mal nachschauen?
Gruß
17. August 2008 um 12:55
@ocean90: Ich habe es auch unter 2.7 beta laufen, ohne Probleme. Hast du die Konstante definiert?
19. August 2008 um 12:53
hallo vielen dank für die performancetipps. wie kann ich denn eine wordpress installation noch monitoren? bzw. das serververhalten? wie kann ich eine high-traffic-wordpressinstallation optimieren? wie kann ich denn punkt für punkt bestimmte sachen ausschließen? kann ich z.B. mir die /index.php vornehmen (also jede seite einzeln) und nach allen kriterien hin durchprüfen?
gruß
juniman
19. August 2008 um 12:58
@juniman: Dazu gibt es hier keine Infos bisher und ich habe sie gerade erarbeitet für das kommende Buch von mir. Serverhalten kann man eigentlich nur sauber über einen eigenen Server oder entsprechenden Mietserver tracken. Bei Hightraffic helfen viele kleine Details, Super Cache als Plugin macht einen recht guten Fortschritt.
1. September 2008 um 22:34
Ich habe es ganz genauso gemacht wie beschrieben und bekomme diese Fehlermeldung:
Warning: Cannot modify header information - headers already sent by (output started at garten/wp-config.php:23) in garten/wp-includes/pluggable.php on line 770Wo war ich noch blond?
1. September 2008 um 22:36
beim secure-wordpress-plugin das gleiche....
2. September 2008 um 08:31
@Nimue: eventuell ein Fehler in deiner Install. Bitte prüfe mal dein wp-config.php, denn der Fehler kommt durch die Mehrsprachigkeit in WordPress. Alternativ würde ich nochmal den Ordner wp-includes neu einspielen, nicht überschreiben.
2. September 2008 um 18:14
Hab ich gemacht, jetzt komme ich nicht mal mehr in mein blog
(
2. September 2008 um 18:26
das sind die meldungen, die ich jetzt bekomme....
Warning: Cannot modify header information - headers already sent by (output started at /www/htdocs/w00686b6/garten/wp-config.php:22) in /www/htdocs/w00686b6/garten/wp-login.php on line 267Warning: Cannot modify header information - headers already sent by (output started at /www/htdocs/w00686b6/garten/wp-config.php:22) in /www/htdocs/w00686b6/garten/wp-login.php on line 279
Warning: Cannot modify header information - headers already sent by (output started at /www/htdocs/w00686b6/garten/wp-config.php:22) in /www/htdocs/w00686b6/garten/wp-includes/pluggable.php on line 595
Warning: Cannot modify header information - headers already sent by (output started at /www/htdocs/w00686b6/garten/wp-config.php:22) in /www/htdocs/w00686b6/garten/wp-includes/pluggable.php on line 596
Warning: Cannot modify header information - headers already sent by (output started at /www/htdocs/w00686b6/garten/wp-config.php:22) in /www/htdocs/w00686b6/garten/wp-includes/pluggable.php on line 597
Warning: Cannot modify header information - headers already sent by (output started at /www/htdocs/w00686b6/garten/wp-config.php:22) in /www/htdocs/w00686b6/garten/wp-includes/pluggable.php on line 770
2. September 2008 um 20:45
@Nimue: Da scheint aber ein Problem vorzuliegen; ich kann so nicht viel helfen. Kannst du mir deine wp-config.php senden. Welche WordPress Version ? Tritt das Problem auch auf wenn alle Plugins deaktiv sind dun wenn ja auch wenn du das Standard-Theme nutzt, wobei das wohl keinen Einfluss hat.
2. September 2008 um 21:07
ich habe 2.6.1 und bis ich versucht habe, diese plugin laufern zu lassen,w ar alles in ordnung
ich würde gern die config schicken, ich finde nur keine mailaddi von dir.
2. September 2008 um 21:19
@Nimue: siehe Impressum bzw. wenn du die Kommentare per Mail abonniert hast, dann bekommst du sie automatisch.
17. Dezember 2008 um 23:29
31. Dezember 2008 um 14:03
Thanks to this article I reduced the number of SQL queries on my index page from 45 down to 16! Great job!
20. Januar 2009 um 10:41
hi
läuft dieser Plugin auch unter Wordpress 2.7 ?
Ich habe Wordpress 2.7 installiert und benutze default theme, Wordpress erzeugt ca 22 queries was für mich zuviel ist. Modx kommt mit 4-7 queries aus wieso ist sowas nicht unter Wordpress möglich?
Ich habe in Sidebar fast alles ausgeklammert aber kann die 22 queries nicht reduzieren
was mache ich denn falsch?
20. Januar 2009 um 10:51
@junyk: läuft unter 2.7; die Queries wirst du aber nicht sonderlich senken können. Die Version 2.7 hat da schon Verbesserungen im Bauch, trotzdem ist ein Wert um 25 sehr realistisch.
22. Februar 2009 um 11:12
31. März 2009 um 08:50
Moin moin,
die 0.1er Version funktionierte bei mir nicht. Jetzt die Version 0.2 funktioniert besser, aber auch nicht wirklich vollständig.
Total query time: $total_query_time for 25 queries.
$total_query_time wird nicht aufgelöst?
Nur mal so als Hinweis ...
31. März 2009 um 12:40
@mg: hm, habe ich noch nie erlebt. Kann mir aktuell auch keinen Reim machen. Hast du es mal mit einem anderen Theme versucht?
31. März 2009 um 12:53
@Frank:
... __('Total query time: $total_query_time for') ...
=>
... __("Total query time: $total_query_time for") ...
31. März 2009 um 13:38
@mg: danke, habe den Bug gefixt.
31. März 2009 um 16:32
... mir ist noch eine Kleinigkeit aufgefallen ...
$wpdb->num_queries bei mir im Template = 29 Abfragen
Das Plugin zeigt nur 25?
Ich glaube die Ausgabe - der Hook - ist zu früh.
31. März 2009 um 20:26
@ms: aber im Frontend kann ich nicht später einhooken, eventuell kommt nach deinem Hook im Theme noch einiges an Code.
31. März 2009 um 21:12
@Frank: Ausgabe kann auch noch später modifiziert werden, aber auch wenn ich das Plugin anpasse sind die Anzahl der Queries immer noch verschieden
... crazy?
2. April 2009 um 13:28
Bin gerade durch Zufall über Dein PlugIn gestolpert und finde es interessant zu sehen was diverse PlugIns oder auch Wordpress so treibt. Kleiner Vorschlag: ich hab mal spasseshalber das PlugIn erweitert, dass es alle SELECT's nochmal mit "EXPLAIN " davor an die DB schickt und die Ergebnisse an die Queries anhängt damit man sieht, wenn jemand vollkommenen Murks gebaut hat
Das wäre vielleicht noch eine interessante Erweiterung für eine spätere Version.
Ansonsten ein wirklich tolles PlugIn!
2. April 2009 um 13:43
Wäre schön, wenn du den Code sendest, dann kann ich einfach erweitern, testen, frei geben - das schöne an GPL. So muss ich mich erst damit beschäftigen, egal wie klein die Änderung ist.
15. April 2009 um 09:36
@Frank: Hab mir noch mal kurz das Delta zwischen
$wpdb->num_queries;und$wpdb->queriesangesehen.mysql query log zeigt in meiner lokalen Umgebung die folgenden zusätzlichen Queries an.
SET NAMES 'utf8'SELECT option_value FROM wp_options WHERE option_name = 'siteurl'
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
SELECT option_value FROM wp_options WHERE option_name = 'aiosp_donate' LIMIT 1
17. April 2009 um 09:50
Try this one:
http://wordpress.org/extend/plugins/sqlmon/It is more feature-rich
18. April 2009 um 13:50
Bin an einer neuen Version dran, lade die heute noch hoch. Aber ich kann die Unterschiede nicht feststellen, es sei denn, ich habe nach dem Hook
wp_footerim Theme noch aufrufe.18. April 2009 um 19:30
Sollten die Statements chronologisch im Log protokolliert werden, ist das Delta vor den durch das Plugin angezeigten Abfragen.
18. April 2009 um 21:11
@mg: erkläre mal, habe ich nicht verstanden.
19. April 2009 um 13:55
@Frank: Naja, die nicht angezeigten Abfragen sind vor dem Hook
wp_footer. Die werden aus was für einen Grund auch immer nicht im Objekt gehalten?20. April 2009 um 11:41
@Frank: Ich habs ...
if ( !defined('SAVEQUERIES') )define('SAVEQUERIES', true);
... wird durch das Plugin erst nach einigen Queries gesetzt.
Die ersten vier werden aufgelistet, wenn der Wert früher (
wp-config.php) gesetzt wird.Alles wird gut!
20. April 2009 um 14:58
@mg: ah, dass ist endlich eine Lösung, eventuell sollte ich dann darauf hinweisen.
21. April 2009 um 14:11
Eine coole Sache! Danke dafür. Ich schau es mir mal genauer an
22. April 2009 um 09:55
@mg: habe nochmal geschraubt, auch weil es unter 2.6 - 2.7 keine saubere Einbindung des SS-Pfades gab, seit 2.8 ist die Funktion besser. Habe nun aber einen kleinen Hinweis drin, wenn es verschiedene Werte gibt.
30. November 2009 um 15:26
Hm. Bei mir schmeisst das Plugin, wenn ich es aktivere eine leere Seite aus.
Habe die neueste WP-Version drauf. Any hints?
30. November 2009 um 15:47
@Patrick: eventuell ist dein CSS so, dass es die Ausgabe des Plugins formatiert und du es nur nicht lesen kannst; schaue mal, ob es Inhalt im Bereich gibt.
30. November 2009 um 16:14
@Frank
Nee. Liegt sicher nicht an CSS weil im Quelltext überhaupt nix steht. Er rendert also überhaupt kein HTML raus.
30. November 2009 um 16:21
@Patrick: hm, du bist aber angemeldet, als Admin? der Hook wp_footer() ist auch im Theme?
30. November 2009 um 16:24
Yep, der Hook ist drin. Als Admin bin ich drin. Es passiert aber auch wenn man nicht eingeloggt ist!
3. Dezember 2009 um 08:39
@Patrick: schwer zu sagen; könnte ich als Admin zugreifen und mir das Problem ansehen?