WordPress und die suboptimale MySQL-Optimierung (5.0.51)

Problem

Es ist ja lobenswert, daß Strato relativ schnell die MySQL-Versionen aktualisiert, vor ein paar Tagen von 5.0.45 auf 5.0.51. Man sollte auch denken, daß es dadurch mit Applikationen keine Probleme geben dürfte. Nich so diesmal, denn plötzlich stimmte bei so manchen WordPressinstalltionen die Sortierreihenfolge der Beiträge nicht mehr, wie mehrere Nutzer im WP-Deutschlanforum beklagten. Aber nicht nur Strato war davon betroffen, auch bei 1&1 und anderen Hostern gab es Probleme.

Normalerweise kommen ja die neuesten Artikel zuerst, es wird also absteigen nach Datum sortiert. Nun waren aber plötzlich die ältesten Beiträge ganz oben, als scheinbar eine umgekehrte, also aufsteigende Sortierung. Und niemand hatte bewußt etwas verändert, also keine Plugins installiert oder die Themedateien bzw. die Konfiguration angepaßt. Also konnte es nur am Hoster liegen. Da ich hier bei Schnurpsel diesen Effekt nicht beobachten konnte, dachte ich zunächst doch an irgendein Plugin, bis ich mal spaßeshalber mein WordPress-2.0.x-Testbolg aufgrufen hatte. Und siehe da, auch hier waren die Beiträge plötzlich nicht mehr in der gewünschten Reihenfolge. Da ich dort aber wirklich seit Monaten nichts verändert hatte und nur ein paar eigene Plugins verwende, mußte es doch irgendeine andere Ursache haben. Zumindest hatte ich jetzt die Chance, der Sache auf den Grund zu gehen.

Hintergrund

Meine erster Schritt war, mir mal die von WP generierte SQL-Abfrage anzusehen. Meine Vermutung war zunächst, daß irgendwo die Sortierung (ORDER BY post_date) verloren geht. So sieht die SQL-Abfrage aus:

SELECT DISTINCT *
 FROM wp20_posts
 WHERE 1 =1
 AND post_date_gmt <= '2008-01-11 22:03:59'
 AND (
  post_status = 'publish'
  OR post_author =1
  AND post_status != 'draft'
  AND post_status != 'static' 
 )
 AND post_status != 'attachment'
 GROUP BY wp20_posts.ID
 ORDER BY post_date DESC
 LIMIT 0 , 10

Vom komischen WHERE 1=1 mal abgesehen gab es zumindest keine Auffälligkeiten, die Sortierung ist auch drin aber was soll bitte das GROUP BY wp20_posts.ID? Das Feld ID ist ein Autoinkrement-Feld, also immer eindeutig (UNIQUE) und somit kann es da nie zwei- oder mehrmals den selben Wert geben, also kann auch nichts gruppiert werden. Mit GROUP BY feldname werden normalerweise Datensätze zusammengefaßt, die in dem oder den angegebenen Feldern die selben Werte enthalten. Ein Blick in den Quelltext gibt dann Aufschluß, dieses GROUP BY ist beim Zusammensetzen des SQL-Strings fest codiert und muß daher immer belegt werden, damit die Abfrage syntaktisch richtig ist:

"SELECT $distinct * FROM $wpdb->posts $join WHERE 1=1" . $where . " GROUP BY " . $groupby . " ORDER BY " . $orderby . " $limits";

Wenn keine echte Gruppierung verwendet wird, wird dafür einfach als Dummy-Wert das Feld ID eingesetzt. Normalerweise kein Probem, weil ja eben dadurch nichts gruppiert wird. Und genau deshalb wird sowas auch vom SQL-Server letztendlich wegoptimiert, daß heißt, es steht zwar da, kommt aber nicht zur Anwendung. Außerdem bewirkt ein GROUP BY auch implizit eine Sortierung nach den dort angegebenen Feldern. Und genau hier liegt das Problem.

Wurde bei MySQL vor Version 5.0.51 mit dem GROUP BY für eindeutige Felder auch die implizite Sortierung wegoptimiert, ist das in der neuen Version nun anders. Hier bleit diese Sortierung erhalten, auch wenn keine Gruppierung stattfindet. In den Release-Notes findet man den entsprechenden Hinweis zu diesem Fehler (30596).

Lösung

Betroffen ist, sofern nicht durch Plugins Gruppierungen hinzugefügt oder verändert werden, nur WordPress Version 2.0.x, zu WP 1.x kann ich nichts sagen. Bei WordPress ab Version 2.1 wurde das Verhalten geändert, so daß GROUP BY nur noch dann in den SQL-String eingebaut wird, wenn wirklich eine Gruppierung verwendet werden soll.
Nachtrag: Auch in WordPress ab Version 2.1 kann das Problem auftreten, wenn man etwas mit Kategorien oder Tags (ab 2.3) verändert, also z.B. nur bestimmte Kategorien in die Anzeige einbeziehen will:

<?php query_posts( $query_string.'&cat=1,2,3' ); ?>

Falls man keine spezielle Kategorie- oder Tagkonfiguration verwendet, ergibt sich auch direkt die erste Lösungsmöglichkeit, nämlich auf die neuste WordPress-Version (derzeit 2.3.2) zu aktualisieren.
Falls man das aus irgendeinem Grund nicht möchte oder das Kategorie-/Tagproblem auftritt, ist die zweite Lösung ein Plugin, welches das GROUP BY auf einen nicht störenden Wert zurechtbiegt.
Als WordPress-Plugin sehen die paar Zeilen PHP-Code dann so aus:

<?php
/*
Plugin Name: 123 No Group By ID
Plugin URI: http://schnurpsel.de/wordpress-und-die-suboptimale-mysql-optimierung-5051-74/
Description: Ändert bei WP das GROUP BY id in GROUP BY post_date (Problem ab MySQL 5.0.51).
Author: Ingo Henze
Version: 0.12
Author URI: http://putzlowitsch.de/
*/ 

	// GROUP BY auswerten
	function plw123ngb_posts_groupby( $groupby ) {
		if( preg_match( "/(|[ ,.])id(|[ ,])/i", $groupby ) ) {
			// sonst GROUP BY auf post_date setzen	
			$groupby = 'post_date';
		}
		return $groupby;
	}

	add_filter( 'posts_groupby', 'plw123ngb_posts_groupby' );
?>

Mann kann den Quelltext hier einfach rauskopieren, in einer Datei speichern, auf den Server in das Pluginverzeichnis kopieren und aktivieren. Oder man nimmt das fertige Plugin als ZIP-Datei.

Download: 123 No Group By ID 0.12

Sofern in der "GROUP BY"-Felderliste das Feld ID auftaucht, wird alles durch POST_DATE ersetzt. Das ist zwar so ein bißchen eine "Holzhammermethode", sollte aber in den meisten Fällen keine Nebenwirkungen zeigen. Probleme könnten nur dann auftreten, falls ein Plugin auch irgendwelche Gruppierungen vornimmt und dabei ebenfalls das Feld ID mit einbezieht. Zudem würde für den eher unwahrscheinlichen Fall, daß es zwei oder mehrere Beiträge mit exakt dem selben Veröffentlichungszeitpunkt gibt, nur einer von diesen angezeigt werden.

42 Reaktionen zu “WordPress und die suboptimale MySQL-Optimierung (5.0.51)”

  1. […] seinem Schnurpsel-Blog geht Ingo detailliert auf die Gründe für die falsche Sortierung ein. Betroffene können dort auch […]

  2. Doc sagt:

    Hi Ingo, das plugin ist wahrhafter Strato-Support. Mal daran gedacht, dort zu arbeiten *g*? Kleiner Hinweis noch: im Code des plugins sind in der ersten Zeile zwei ?? vor dem php. Tippfehler :-)

    Gruß aus Berlin, Daniel

  3. Neee, laß mal gut sein. Strato- oder sonstiger Support wären nicht mein Ding :-)

    Danke für den Hinweis, habe das doppelte Fragezeichen entfernt. Im Download war es glücklicherweise nicht drin, nur auf der Seite selbst.

  4. Ina sagt:

    Vielen Dank!

    Habe heute recht dumm aus der Wäsche geguckt, als die Reihenfolge meiner Beiträge plötzlich „falschrum“ war.
    Über eine Suchmaschine und einige Umwege stieß ich auf diese Seite.
    Habe eben dein Plugin installiert, und – YEAH! – alles passt wieder.

    Ich verbeuge mich.

    Vielen, vielen Dank für die Rettung!!!

    Herzliche Grüße, Ina.

  5. […] (16.01.2008) Inzwischen habe ich (danke, Dirk!) auch einen Blog-Eintrag gefunden, der zusammenfassend erklärt, wie das Problem überhaupt zustande kommt: SQL-Code, der […]

  6. schneeengel sagt:

    bin dir zu tiefst zu dank verpflichtet… ich war schon völlig verzweifelt!!! jetzt endlich funktioniert der blog wieder… danke dir! :)

  7. Bernd sagt:

    Ich staunte nicht schlecht als viele Mitglieder unseres Motorsportclubs
    http://www.msc-altena.de
    mich auf unseren „zerstörten “ Blog aufmerksam machten.
    Da ich mich eher für PS als php interessiere war ich der Verzweifelung nahe.
    Aber Dank Google ind diesem tollen Blog konnte das Problem in Windeseile gelöst werden.
    Also langer Rede kurzer Sinn:
    Schnurpsel kommt auf meine Fovoritenliste.
    Alle Mitglieder sind wieder zufrieden.
    Ich verbeuge mich in Dankbarkeit ;-)

  8. […] Schuldiger entdeckt! No Comments, Comment or […]

  9. […] und sonst was für dateien durch – ohne ergebnis… jetzt endlich stieß ich im netz auf den post von schnurpsel. strato hatte die mysql-datenbank aktualisiert und dabei ist wohl was nicht ganz so optimal […]

  10. Renate sagt:

    Vielen Dank für das Plugin. Ich verstehe zwar nichts davon, aber ich hab den Link an meinen Computerfreak weiter geleitet, der hat es in mein Blog eingebaut und nun läuft die Sortierreihenfolge wieder so wie sie soll.

    Ganz herzlichen Dank, lieber Schnurzel – auch von meinem Computerfreak, und der ist auch SEHR fit. Aber du hast ihm mit dem Plugin Arbeit erspart! :-)

    Lieber Gruß von Renate

  11. […] Nachtrag: Lösung gefunden: Siehe hier  […]

  12. Erich sagt:

    Vielen, vielen Dank für das Plugin!!! Es hat mich gerettet (Blog bei 1&1, seit ca. 1.2. umgekehrte Reihenfolge!)!! Das war nach Stunden des Rumprobierens und der Websuche dann echt die Erleuchtung!!! Danke!!

  13. Bufko sagt:

    Ich liebe dich. Nein, ehrlich, zwei! Plugins und beide haben mir extrem geholfen, vielen, vielen Dank =)

  14. […] Falls jemand das glеiсhe Problem haben sollte, rauft euch nicht länger die Haare, sondern geht hier hin und installiert das Plugin unten auf der Seite. Oh und ein einfaches Update auf die neuste […]

  15. Björn sagt:

    Danke! Danke! Danke!

  16. yedermann sagt:

    Danke! Unser Retter!

  17. Raphael sagt:

    ich habe meine beiträge von einem cms convertiert und dadurch haben sie alle das glеiсhe datum (exact auf die sekunde)!
    was kann ich machen damit er bei mir nach namen sortiert

    hab schon probiert anstatt dem post_date einfach post_title bzw post_name reinzuschreiben was aber beides keine veränderung bringt

  18. Danke !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!……

  19. Boris Wollny sagt:

    Dein Plugin war ein große Hilfe! Ich war mit meinem beschränkten PHP und MySQL Latein am Ende.

    Ich werde hier künftig öfter vorbeischauen.

  20. Timo sagt:

    Hilfe, dein Plugin ging bis gestern einwandfrei. Seit heute schmeißt es mir allerdings eine Fehlermeldung raus:

    WordPress database error: [You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‚ORDER BY post_date DESC LIMIT 0, 10‘ at line 1]

    Wenn ich dein Plugin deaktiviere, ist die Fehlermeldung allerdings wieder weg. Kannst Du mir helfen?

  21. Verwendest Du die aktuelle Plugin-Version 0.12? Falls nicht, probiere es bitte mit der aktuellen Version. Der Fehler tritt auf, weil die GROUP BY – Klausel leer ist, also es steht da folgendes:

    ... GROUP BY  ORDER BY post_date DESC LIMIT 0, 10

    Das kann eigentlich nicht passieren, denn mein Plugin gibt entweder ‚post_date‘ oder den originalen Wert zurück.

  22. Timo sagt:

    Ok, ich hab die Version 0.11. Dann probier ich das mal aus und atme erstmal tief durch.

  23. Timo sagt:

    Ich danke Dir ganz ganz herzlich! Absolut top!!!

  24. Laurent sagt:

    Hi!

    Habe einen Blog noch unter 1.5.2 (zu sehr customised um ein Upgrade zu machen, der letzte Upgrade schlug zudem fehl).

    Trotz deines Plugins habe ich immer nochd en selben Fehler. Irgendein Tipp?

  25. Mit 1.5.x funktioniert das Plugin nicht, weil es den erforderlichen Filter-Hook für die „GROUP BY“ SQL-Klausel nicht gibt. Du mußt hier direkt die WP-Datei anpassen:
    – öffne die Datei /wp-includes/classes.php
    – suche nach der Zeile:

    $where .= " GROUP BY $wpdb->posts.ID";

    – ersetze ID durch POST_DATE

    Das sollte genau so funktionieren, wie mein Plugin.

  26. Laurent sagt:

    Hammer !!! Funzt !! Vielen lieben Dank!!!! :-)

  27. Jule sagt:

    Wollte dir nur eben Danke für das Plugin sagen – suche seit Tagen nach einer Lösung und hatte dein Plugin auch ausprobiert – hatte aber das Custon Query String aktiviert (auch wegen des Problems, weil man damit ja auch sortieren kann :D)… bis ich dann endlich auf den Draht kam ^^
    Also vielen Dank!!

  28. […] habs geschafft! GLN.net läuft wieder ohne Probleme! Naja, eigentlich gilt aller Dank “Schnurpsel” für sein wunderbares Plugin, das den Fehler behoben hat! (Falls es euch auch passieren […]

  29. […] falschen Startseiten Sortierung – der einfachste Weg ist die Installation folgenden Plugins namens 123 No Group by ID, von der Domain http://www.schnurpsel.de. Themeirrelevant: hab ne gute Freundin (Mitte 50) in Berlin, die […]

  30. danke..: Schnurpsel » WordPress und die suboptimale MySQL-Optimierung (5.0.51)…

    ……

  31. Frank sagt:

    Thanks for this. Really helped me with a problem on my site, where all posts where appearing in reverse order.

  32. Guy sagt:

    Hi,

    Vielen, vielen Dank für die plug-in!!!

    Gruß aus London, England!

  33. Loic M sagt:

    Merci, thank you, danke!

    Ce plugin est une merveille qui a souvé mes blogs!
    (this plugin is a wonder that saved my weblogs!)

    Je répète: merci, merci, merci !

  34. […] dank Schnurpsel war das schnell geloest. […]

  35. olli sagt:

    DANKE. Glücklich über die für mich schnelle Lösung und die Rettung sende ich Grüße!

  36. […] themes have this error when calling from the database, I’ve used this in the past to fix it… Schnurpsel

  37. Oliver sagt:

    Vielen Dank,
    hab schon den ganzen Tag nach einer Lösung gesucht und nun endlich gefunden.
    grüße
    Oliver

  38. […] habe ich das Netz nochmal genau befragt und endlich eine Lösung gefunden. Der Fehler wird durch eine Änderung in MySQL (Server-Update) verursacht und betrifft nur […]

  39. Steffan sagt:

    Let me know if you find something that works. I need something like this for another project.

  40. […] falschen Startseiten Sortierung – der einfachste Weg ist die Installation folgenden Plugins namens 123 No Group by ID, von der Domain http://www.schnurpsel.de. Themeirrelevant: hab ne gute Freundin (Mitte 50) in Berlin, die […]

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

 Hier kein Häkchen setzen
 Ich bin kein Spambot

Hinweis: Kommentare von bisher unbekannten Schreibern (Name und eMail) oder mit mehr als einem Link werden moderiert.