Le WordPress d'aujourd'hui, décodé pour les développeurs

Hébergement & serveurs

Indexer la table wp_options pour accélérer la lecture des réglages autoload sur un cluster mutualisé

Un index composite bien choisi sur wp_options peut réduire drastiquement le coût d'une requête exécutée sur chaque chargement de page, à volume d'options inchangé.

Par WordPress Développement • 7 septembre 2023 • 5 min de lecture • Aucun commentaire
Indexer la table wp_options pour accélérer la lecture des réglages autoload sur un cluster mutualisé

SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes' : cette requête, générée par le cœur de WordPress à chaque chargement de page via la fonction interne wp_load_alloptions(), s’exécute des dizaines de milliers de fois par jour sur un cluster mutualisé hébergeant plusieurs centaines de bases WordPress.

Ce billet documente l’ajout d’un index composite adapté à ce filtre précis, sur un cluster où plusieurs bases dépassaient les dix mille lignes dans wp_options, sans que la réduction du volume d’options autoloadées elle-même n’ait encore pu être menée, faute de temps disponible côté équipe applicative.

Pourquoi cette requête pèse plus qu’il n’y paraît

La fonction wp_load_alloptions() charge en une seule fois toutes les options marquées autoload = 'yes' et les place en cache d’objet pour le reste de l’exécution de la page. Sur un site bien tenu, ce jeu de données reste limité à quelques centaines de lignes. Mais un nombre croissant d’extensions marquent leurs propres réglages en autoload par défaut, sans que l’administrateur du site n’en ait toujours conscience, et ce volume grossit silencieusement au fil des installations d’extensions successives.

Sans index adapté au filtre sur autoload, MySQL doit parcourir l’intégralité de la table pour isoler les lignes concernées, un balayage complet dont le coût croît linéairement avec le nombre total de lignes de la table, autoloadées ou non. Sur la base la plus chargée du cluster observé, cette requête consommait en moyenne 340 millisecondes avant intervention, un délai qui s’ajoutait à chaque chargement de page, y compris pour un simple article de blog sans logique métier complexe.

L’index composite qui cible exactement ce filtre

La table wp_options possède nativement un index sur option_name, mais aucun index par défaut sur la colonne autoload seule. L’ajout d’un index composite couvrant à la fois autoload et les colonnes lues par la requête permet à MySQL de répondre directement depuis l’index, sans accéder aux lignes complètes de la table.

ALTER TABLE wp_options
  ADD INDEX autoload_options (autoload, option_id);

Ce choix d’index, volontairement restreint à autoload et à la clé primaire option_id, évite de dupliquer inutilement le contenu potentiellement volumineux d’option_value dans l’index lui-même, ce qui aurait alourdi les écritures sans bénéfice proportionné en lecture.

L'essentiel à retenir : la requête autoload s'exécute à chaque chargement de page WordPress ; un index composite adapté cible exactement le filtre utilisé ; l'effet se mesure surtout sur des bases dépassant plusieurs milliers d'options

Vérifier l’effet réel avec EXPLAIN avant et après

Avant toute application sur le cluster de production, la commande EXPLAIN a permis de confirmer que le plan d’exécution utilisait bien le nouvel index plutôt que de continuer à balayer la table intégralement, un point qui n’est jamais garanti automatiquement selon la répartition des valeurs de la colonne indexée.

  • Avant l’index : type ALL dans le plan d’exécution, balayage complet de la table, coût proportionnel à son volume total.
  • Après l’index : type ref, utilisation directe de l’index autoload_options, coût proportionnel au seul sous-ensemble des lignes autoloadées.
  • Le gain observé sur la base la plus chargée du cluster a fait passer le temps moyen de la requête de 340 millisecondes à moins de 15 millisecondes, sans aucune modification côté applicatif.

Ce que cet index ne résout pas

Cette intervention agit exclusivement sur le coût de lecture de la requête, pas sur le volume de données transférées et mises en cache d’objet à chaque exécution. Une base avec quinze mille lignes autoloadées continuera de transférer un volume important de données à chaque chargement de page, même avec un index parfaitement adapté au filtre. La réduction de ce volume, en identifiant les extensions qui autoloadent des réglages volumineux sans nécessité réelle, reste un chantier distinct, non traité ici.

Un index accélère l’accès à des données ; il ne réduit jamais leur volume. Les deux chantiers sont complémentaires, rarement substituables l’un à l’autre.

Déploiement prudent sur un cluster mutualisé

L’ajout de cet index a été déployé progressivement, base par base, plutôt qu’en un script global appliqué à l’ensemble du cluster en une seule opération. Sur MySQL 8, l’opération ALTER TABLE ... ADD INDEX s’exécute en ligne par défaut sans verrouillage bloquant prolongé sur cette table de petite taille relative, mais la prudence a primé sur un cluster où chaque base sert un client de production différent, avec des contraintes de disponibilité propres.

En résumé

Un index composite ciblant précisément le filtre autoload = 'yes' a permis de diviser par plus de vingt le temps de la requête la plus fréquemment exécutée par WordPress sur ce cluster, sans toucher au code applicatif ni réduire le volume de réglages autoloadés. Cette intervention, simple et peu risquée, ne dispense toutefois pas d’un travail complémentaire sur le volume d’options lui-même, seul capable de réduire durablement la quantité de données transférées à chaque chargement de page.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi