Langsame Abfrage für die Tabelle wp_options


16

Ich habe das Protokoll langsamer Abfragen der WP-basierten Site verfolgt (mit dem Standardwert von a long_query_time von 10) und festgestellt, dass die folgende Abfrage häufig protokolliert wird:

# User@Host: root[root] @ localhost []
# Query_time: 0  Lock_time: 0  Rows_sent: 394  Rows_examined: 458
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';

Ich verstehe nicht, wie lange es dauern kann, eine so kleine Tabelle auszuführen. Ist dies nur ein Symptom für ein anderes Problem? (Derzeit werden Moodle, phpbb und WP auf einer dedizierten VM ausgeführt.)

Antworten:


16

Update : Der Grund für die Protokollierung der Abfrage ist, dass kein Index verwendet wird . Die Abfragezeit ist 0, dh sie wird tatsächlich schnell ausgeführt. Sie können die Option "Protokollabfragen, die keine Indizes verwenden" deaktivieren, wenn diese nicht protokolliert werden sollen.

Die Tabelle wp_options hat keinen Index für das automatische Laden, sodass die Abfrage einen vollständigen Tabellenscan ausführt. Im Allgemeinen sollte diese Tabelle nicht zu groß werden, es ist also kein Problem, aber ich vermute, dass das in Ihrem Fall irgendwie passiert ist.

Das Hinzufügen eines Indexes könnte das Problem lösen, aber wie TheDeadMedic in den Kommentaren hervorhob, ist dies möglicherweise nicht der Fall, wenn die Autoload-Werte entweder mit der Mehrheit Ja oder gleichmäßig zwischen Ja und Nein verteilt sind:

Führen Sie zuerst diese Abfrage aus, um zu sehen, wie die Verteilung aussieht:

SELECT COUNT(*), autoload FROM wp_options GROUP BY autoload;

Wenn eine große Mehrheit von ihnen auf "Nein" gesetzt ist, können Sie das Problem vorerst lösen, indem Sie einen Index für das automatische Laden hinzufügen.

ALTER TABLE wp_options ADD INDEX (`autoload`);

Vielleicht möchten Sie jedoch herausfinden, warum diese Tabelle zu groß geworden ist. Vielleicht ein schlecht geschriebenes Plugin, das etwas faul macht.


2
Ich bezweifle, dass ein Index in diesem Fall einen Gewinn bringen würde - lesen Sie diesen Artikel zur Kardinalität .
TheDeadMedic

Hängt davon ab, ob die meisten Optionen auf Autoload eingestellt sind oder nicht. Ich würde nicht denken, aber in der Tabelle sollte sowieso nie so groß werden, damit etwas faul los ist.
Vinay Pai

1
Ich habe die Antwort aktualisiert, um ein wenig über die Überprüfung der Werteverteilung hinzuzufügen.
Vinay Pai

1
Ich habe gerade den Kommentar bemerkt und festgestellt, dass meine Antwort völlig falsch ist. Die Abfrage ist nicht wirklich langsam. Sie wird nur im Protokoll für langsame Abfragen protokolliert, da kein Index verwendet wird.
Vinay Pai

1
Dank dieser Frage und Antwort entdeckte ich, dass meine wp_options-Tabelle 90.000 Einträge enthielt, von denen 88.5.000 auf Autoload false eingestellt waren. Der Rest waren alle "transienten" Einträge, die durch Plugins hinzugefügt wurden (vermutlich zum Cachen?). Durch das Hinzufügen eines Index zur Autoload-Spalte wurde meine mySql-Last sofort von durchschnittlich 89% auf 2,5% gesenkt. Überwachungsagenten zeigen, dass die Antwortzeit meiner Site von 1900 ms auf 500 ms gesunken ist. Dies war ein Gamechanger für mich.
Mordred

5

Ich bin vor ein paar Tagen auf die in mytop erwähnte Abfrage gestoßen, die auf meinem Server ausgeführt wird - und es hat tatsächlich einige Zeit (ungefähr 10 Sekunden) für jede Abfrage gedauert! Es gibt also Situationen in der realen Welt, in denen wp_options zu einer problematischen Größe werden kann. In meinem Fall vermute ich, dass das Caching-Plugin Cachify für das Aufblähen von wp_options verantwortlich ist.

Daten dieser speziellen wp_options:

5,309 rows
130MB of data

Als Lösung habe ich den Index hinzugefügt, der der von Vinay Pai veröffentlichten Lösung ähnelt, wodurch das Problem einwandfrei gelöst wurde.


1

Meine wp_options-Tabelle enthielt nur ungefähr 235 Datenzeilen. Ich habe versucht, die Tabelle zu indizieren, aber es hat nicht geholfen.

Es stellte sich heraus, dass ungefähr 150 vorübergehende Optionen in die Tabelle eingefügt, aber nicht automatisch gelöscht wurden.

Ich weiß nicht, ob es verwandt ist oder nicht, aber ich habe meine /var/log/apache2/access.log-Dateien durchsucht und festgestellt, dass mehrere (vermutlich gefährdete) Amazon Web Services-Server (IP-Adressen beginnen mit 54). XXX und 32.XXX) hatten versucht, /~web-root-dir/xmlrpc.php auszunutzen.

Nach einiger Fehlerbehebung habe ich die Tabelle wp_options nach Optionsnamen abgefragt, die "transient" enthielten.

Wählen Sie * aus wp_options, wobei option_name '% transient %' entspricht.

Eines der von dieser Abfrage zurückgegebenen Felder ist 'option_value' mit dem Datentyp LONGTEXT. Gemäß den mySQL-Dokumenten kann ein LONGTEXT-Feld (für jede Zeile) bis zu 4 Gigabyte Daten enthalten.

Als ich die Abfrage ausführte, enthielten einige der Zeilen (denken Sie daran, sie arbeiteten mit solchen, die "transient" enthielten) riesige Datenmengen im Feld option_value. Als ich mir die Ergebnisse ansah, sah ich auch, wie Versuche aussahen, Befehle in den wp-cron-Prozess einzufügen, mit der Hoffnung, dass sie während des oder der cron-Zyklen ausgeführt würden.

Meine Lösung bestand darin, alle "vorübergehenden" Zeilen zu löschen. Dies schadet dem Server nicht, da "transiente" Zeilen automatisch neu gefüllt werden (wenn sie dort sein sollen).

Danach reagierte der Server wieder.

Abfrage zum Löschen dieser Zeilen:

LÖSCHEN von wp_options wo option_name wie '% transient %';

Ich habe meiner Firewall auch die AWS IP-Adresse / 8 Superblocks hinzugefügt (-:


Ja. Ich litt auch unter "40 Sekunden Ladezeit", bis ich entdeckte, dass 20.000 wp_option-Datensätze mit massiven Daten auf jeder einzelnen Seite geladen wurden. Das Entfernen dieser Elemente beschleunigte die Site erheblich.
JasonGenX
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.