Requête lente pour la table wp_options


16

J'ai suivi le journal des requêtes lentes du site basé sur WP (avec la valeur par défaut de a long_query_time définie sur 10), et j'ai remarqué que la requête suivante est souvent enregistrée -

# 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';

Je ne comprends pas comment une si petite table peut prendre autant de temps à s'exécuter. Est-ce juste un symptôme d'un autre problème? (Exécute actuellement Moodle, phpbb et WP sur une machine virtuelle dédiée).

Réponses:


16

Mise à jour : la raison pour laquelle la requête est enregistrée est qu'elle n'utilise pas d'index . Le temps de requête est 0, c'est-à-dire qu'il s'exécute en fait rapidement. Vous pouvez désactiver l'option "log-queries-not-using-indexes" si vous ne souhaitez pas qu'ils soient enregistrés.

La table wp_options n'a pas d'index lors du chargement automatique, de sorte que la requête finit par effectuer une analyse complète de la table. En général, ce tableau ne devrait pas devenir trop grand, donc ce n'est pas un problème, mais je suppose que cela s'est en quelque sorte produit dans votre cas.

L'ajout d'un index peut résoudre le problème, mais comme TheDeadMedic l'a souligné dans les commentaires, il se peut que ce ne soit pas le cas si les valeurs de chargement automatique sont majoritaires oui, ou réparties également entre oui et non:

Tout d'abord, faites cette requête pour voir à quoi ressemble la distribution:

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

si une grande majorité d'entre eux sont définis sur «non», vous pouvez résoudre le problème pour l'instant en ajoutant un index lors du chargement automatique.

ALTER TABLE wp_options ADD INDEX (`autoload`);

Cependant, vous voudrez peut-être aller au fond des raisons pour lesquelles ce tableau est devenu trop volumineux. Peut-être un plugin mal écrit faisant quelque chose de louche.


2
Je doute qu'un indice dans ce cas offrirait un gain - consultez cet article sur la cardinalité .
TheDeadMedic

Dépend si la plupart des options sont définies sur le chargement automatique ou non. Je ne pense pas, mais de toute façon, le tableau ne devrait jamais être aussi gros, donc quelque chose de louche se passe.
Vinay Pai du

1
J'ai mis à jour par réponse pour ajouter un peu sur la vérification de la distribution des valeurs.
Vinay Pai du

1
Je viens de remarquer le commentaire et j'ai réalisé que ma réponse était complètement fausse. La requête n'est pas vraiment lente ... elle est simplement enregistrée dans le journal des requêtes lentes car elle n'utilise pas d'index.
Vinay Pai du

1
Grâce à cette question et à ma réponse, j'ai découvert que j'avais 90 000 entrées dans ma table wp_options, dont 88,5 k étaient définies sur autoload false. Les autres étaient toutes des entrées "transitoires" ajoutées par des plugins (probablement pour la mise en cache?). L'ajout d'un index à la colonne de chargement automatique a fait chuter instantanément ma charge mySql d'une moyenne de 89% à 2,5%. Les agents de surveillance montrent que le temps de réponse de mon site est passé de 1900 ms à 500 ms. Ce fut un gamechanger pour moi.
Mordred

5

Je suis tombé sur la requête mentionnée dans mytop en cours d'exécution sur mon serveur il y a quelques jours - et cela a pris du temps (environ 10 secondes) pour chaque requête! Il existe donc des situations réelles où wp_options peut atteindre une taille problématique. Dans mon cas, je soupçonne le plugin de mise en cache Cachify d'être responsable des ballonnements wp_options.

Données de ce wp_options particulier:

5,309 rows
130MB of data

Comme solution, j'ai ajouté un index similaire à la solution proposée par Vinay Pai, qui a résolu le problème sans problème.


1

Ma table wp_options ne contenait qu'environ 235 lignes de données. J'ai essayé d'indexer la table, mais cela n'a pas aidé.

Il s'avère qu'environ 150 options transitoires ont été insérées dans le tableau, mais n'ont pas été supprimées automatiquement.

Je ne sais pas si c'est lié ou non, mais j'avais parcouru mes fichiers /var/log/apache2/access.log et remarqué que plusieurs serveurs Amazon Web Services (probablement compromis) (adresses IP commençant par 54). XXX et 32.XXX) tentaient d'exploiter /~web-root-dir/xmlrpc.php.

Après un dépannage, j'ai interrogé la table wp_options pour les noms d'options qui contenaient "transitoire"

sélectionnez * dans wp_options où option_name comme '% transient %';

L'un des champs renvoyés par cette requête est 'valeur_option' qui a un type de données LONGTEXT. Selon les documents mySQL, un champ LONGTEXT (pour chaque ligne) peut contenir jusqu'à 4 gigaoctets de données.

Lorsque j'ai exécuté la requête, certaines des lignes (rappelez-vous qu'elles fonctionnaient avec celles contenant des "transitoires") contenaient d' énormes quantités de données dans le champ option_value. En regardant à travers les résultats, j'ai également vu ce qui ressemblait à des tentatives d'injecter des commandes dans le processus wp-cron avec l'espoir qu'elles seraient exécutées pendant le (s) cycle (s) cron.

Ma solution a été de supprimer toutes les lignes "transitoires". Cela n'endommagera pas le serveur car les lignes "transitoires" se repeupleront automatiquement (si elles sont censées être là).

Après cela, le serveur était à nouveau réactif.

Requête pour supprimer ces lignes:

SUPPRIMER de wp_options où option_name comme '% transient %';

J'ai également ajouté l'adresse IP AWS / 8 superblocs à mon pare-feu (-:


Oui. Je souffrais également de "40 secondes de chargement" jusqu'à ce que je découvre que j'avais 20 000 enregistrements wp_option contenant des données massives chargées à chaque page. La suppression de ceux-ci a considérablement accéléré le site.
JasonGenX
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.