Slow Query Log – Journal des requêtes lentes

Le Slow Query Log (journal des requêtes lentes) est un fichier de log MySQL/MariaDB qui enregistre toutes les requêtes SQL dont le temps d’exécution dépasse un seuil prédéfini. Cet outil de diagnostic permet d’identifier les requêtes problématiques impactant les performances d’un site WordPress.

Fonctionnement

Activation

-- Activer le slow query log
SET GLOBAL slow_query_log = 'ON';

-- Définir le seuil de lenteur (en secondes)
SET GLOBAL long_query_time = 2;

-- Spécifier l'emplacement du fichier de log
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log';

Configuration dans my.cnf / my.ini

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 2
log_queries_not_using_indexes = 1
log_slow_admin_statements = 1
log_slow_slave_statements = 1

Paramètres Clés

ParamètreDescriptionValeur Typique
long_query_timeSeuil de durée pour considérer une requête comme « lente »1-2 secondes
log_queries_not_using_indexesJournaliser les requêtes sans index1 (activé)
log_slow_admin_statementsInclure les commandes administratives1 (activé)
log_slow_slave_statementsInclure les requêtes de réplication0 (désactivé)
slow_query_logActiver/désactiver le journal1 (ON)

Format d’une Entrée de Log

# Time: 2024-01-15T14:23:45.123456Z
# User@Host: wordpress[wordpress] @ localhost []
# Thread_id: 12345 Schema: wordpress_db QC_hit: No
# Query_time: 3.456789 Lock_time: 0.000123 Rows_sent: 1000 Rows_examined: 50000
# Rows_affected: 0 Bytes_sent: 250000
SET timestamp=1705328625;
SELECT * FROM wp_posts
WHERE post_status = 'publish'
AND post_type = 'post'
ORDER BY post_date DESC;

Explication des métriques :

  • Query_time : Temps total d’exécution (3.45s = lent)
  • Lock_time : Temps d’attente des verrous
  • Rows_sent : Lignes retournées au client
  • Rows_examined : Lignes analysées par MySQL (50k = problème potentiel)
  • Bytes_sent : Volume de données transférées

Cas Typiques de Requêtes Lentes dans WordPress

1. Requêtes sans Index

-- Problème : WHERE sur un champ non indexé
SELECT * FROM wp_postmeta WHERE meta_value LIKE '%recherche%';

2. Jointures Multiples

-- Problème : Trop de JOIN
SELECT p.*, u.user_nicename, c.comment_count, t.name
FROM wp_posts p
LEFT JOIN wp_users u ON p.post_author = u.ID
LEFT JOIN wp_term_relationships tr ON p.ID = tr.object_id
LEFT JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN wp_terms t ON tt.term_id = t.term_id
WHERE p.post_status = 'publish';

3. Requêtes sur wp_options

-- Problème : Options non autoloadées ou trop volumineuses
SELECT option_name, option_value FROM wp_options 
WHERE autoload = 'yes' 
AND option_value LIKE '%serialized_data%';

4. Requêtes de Recherche

-- Problème : LIKE avec wildcard en début
SELECT * FROM wp_posts 
WHERE post_title LIKE '%motclef%' 
OR post_content LIKE '%motclef%';

Outils d’Analyse

mysqldumpslow (Outil MySQL natif)

# Afficher les requêtes les plus lentes
mysqldumpslow -s t /var/log/mysql/slow-query.log

# Top 10 des requêtes par temps moyen
mysqldumpslow -s at -t 10 /var/log/mysql/slow-query.log

# Regrouper par requête similaire
mysqldumpslow -g 'SELECT.*wp_posts' /var/log/mysql/slow-query.log

pt-query-digest (Percona Toolkit)

# Analyse détaillée avec statistiques
pt-query-digest /var/log/mysql/slow-query.log > analyse.txt

# Analyse en temps réel
pt-query-digest --processlist h=localhost,u=root,p=password

Plugins WordPress

  • Query Monitor – Analyse en temps réel des requêtes
  • Debug Bar – Barre de débogage avec stats SQL
  • New Relic – Monitoring APM complet

Bonnes Pratiques d’Optimisation

1. Ajouter des Index

-- Index sur wp_postmeta pour les requêtes fréquentes
CREATE INDEX meta_key_value ON wp_postmeta(meta_key, meta_value(191));

-- Index sur wp_comments pour le statut
CREATE INDEX comment_approved ON wp_comments(comment_approved);

2. Limiter les Résultats

// Mauvais : récupérer tout
$posts = get_posts(array('numberposts' => -1));

// Bon : pagination
$posts = get_posts(array('posts_per_page' => 20));

3. Utiliser le Cache

// Transient API pour les requêtes coûteuses
$expensive_data = get_transient('my_expensive_query');
if (false === $expensive_data) {
    $expensive_data = ma_requete_couteuse();
    set_transient('my_expensive_query', $expensive_data, DAY_IN_SECONDS);
}

4. Éviter les Requêtes N+1

// Mauvais : requête dans boucle
foreach ($posts as $post) {
    $author = get_userdata($post->post_author); // Requête à chaque itération
}

// Bon : récupérer tous les auteurs en une fois
$author_ids = wp_list_pluck($posts, 'post_author');
$authors = get_users(array('include' => array_unique($author_ids)));

Seuils de Performance Recommandés

Type de Sitelong_query_timeAction Requise
Blog personnel2s> 5s = investiguer
Site d’entreprise1s> 2s = optimiser
E-commerce0.5s> 1s = critique
High-traffic0.1s> 0.5s = urgence

Impact sur WordPress

Un Slow Query Log bien configuré permet de :

  • Identifier les goulots d’étranglement
  • Mesurer l’impact des plugins/themes
  • Optimiser les performances globales
  • Réduire les coûts d’hébergement
  • Prévenir les problèmes de scalabilité

Workflow de Diagnostic Recommandé

  1. Activer le slow query log (long_query_time = 1)
  2. Laisser tourner 24-48h en production
  3. Analyser avec pt-query-digest
  4. Prioriser les requêtes par impact cumulé
  5. Optimiser les requêtes problématiques
  6. Tester en staging avant production
  7. Surveiller l’amélioration des performances
Les contenus de définition restent publics. Les ressources (outils, grilles, supports) liées à cette fiche sont disponibles dans l’espace membre.