Votre application ralentit. Un endpoint en particulier prend plusieurs secondes à répondre. En remontant la piste, vous isolez une requête SQL lente. Maintenant quoi ? Deviner quels index ajouter ? Tenter des optimisations au hasard ? Arrêtez le bricolage. Dans le monde des bases de données relationnelles, il existe un outil de diagnostic direct et puissant : la commande EXPLAIN. Apprendre à lire ses résultats est la compétence numéro un pour résoudre efficacement les problèmes de performance SQL.
EXPLAIN : Le Scanner Médical de Votre Requête
EXPLAIN n’exécute pas votre requête (sauf avec l’option ANALYZE). Il demande au planificateur de requêtes (query planner) de la base de données de lui expliquer comment il compte l’exécuter. Il vous dévoile le plan d’exécution : la séquence d’opérations (scans, jointures, tris) que le moteur va effectuer, avec une estimation du coût de chacune.
C’est comme si vous demandiez à un expert en logistique de vous décrire, avant de démarrer, le parcours qu’il va emprunter pour livrer un colis, avec les moyens de transport qu’il va utiliser et le temps estimé. Vous pouvez ainsi repérer les étapes inefficaces avant qu’elles ne coûtent du temps et de l’argent.
Comment Utiliser EXPLAIN ?

La commande de base est simple. Placez EXPLAIN devant votre requête SQL lente.
EXPLAIN SELECT * FROM orders WHERE customer_id = 123 AND status = 'shipped';
Pour des informations encore plus précises et réelles, utilisez EXPLAIN (ANALYZE, BUFFERS). ANALYZE exécute réellement la requête et rapporte les temps réels, et BUFFERS montre l’usage du cache.
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE customer_id = 123 AND status = 'shipped';
⚠️ Attention avec ANALYZE sur les requêtes de modification (UPDATE/DELETE), car elle les exécute ! Testez d’abord sur un environnement de staging ou avec un BEGIN; / ROLLBACK;. Pour plus de renseignements, cliquez ici.
Décrypter le Plan d’Exécution : Les Nœuds à Surveiller
Le résultat d’EXPLAIN est un arbre d’opérations, lu de l’intérieur vers l’extérieur (ou du bas vers le haut selon le format). Voici les opérations (nodes) les plus courantes et ce qu’elles signifient.
Le Grand Méchant : Seq Scan (Parcours Séquentiel)
-
Ce que c’est : La base de données lit toutes les lignes de la table, une par une, pour trouver celles qui correspondent.
-
Quand c’est un problème : Sur une grande table (des milliers/millions de lignes). C’est très coûteux.
-
Le remède habituel : Un index sur la (ou les) colonne(s) utilisée(s) dans la clause
WHERE.
Exemple de plan problématique :
Seq Scan on orders (cost=0.00..15523.00 rows=1 width=45) Filter: ((customer_id = 123) AND (status = 'shipped'::text))
Ici, le planificateur estime qu’il devra parcourir 15 523 unités de coût et ne trouvera qu’1 ligne. C’est très inefficace.
Le Héros : Index Scan ou Index Only Scan
-
Ce que c’est : La base de données utilise un index pour localiser rapidement les lignes qui correspondent, puis va les chercher dans la table principale. Un
Index Only Scanest encore mieux : toutes les données nécessaires sont dans l’index, évitant d’accéder à la table. -
C’est ce que vous voulez voir pour les recherches par
WHERE.
Exemple de plan optimisé :
Index Scan using idx_orders_customer_status on orders (cost=0.29..8.31 rows=1 width=45) Index Cond: ((customer_id = 123) AND (status = 'shipped'::text))
Le coût est passé de ~15 000 à ~8. Beaucoup mieux.
Les Autres Opérations Courantes
-
Nested Loop: Jointure où pour chaque ligne de la table A, on scanne la table B. Peut être très lent si B est grande et non indexée. -
Hash Join/Merge Join: Jointures plus efficaces pour des datasets plus grands. -
Sort: Opération de tri. Très coûteuse en mémoire/CPU sur un grand nombre de lignes. Peut être évitée par un index sur la colonne deORDER BY. -
HashAggregate/GroupAggregate: Opérations de regroupement (GROUP BY). Un index peut aussi aider ici.
L’Art de Lire les Chiffres : Coût, Rows et Actual Time
-
cost=0.00..15523.00: Le coût estimé. Le premier nombre est le coût pour renvoyer la première ligne, le second est le coût total. C’est une unité abstraite, mais utile pour comparer deux plans. -
rows=1: Le nombre estimé de lignes qui seront retournées. Si cette estimation est très différente de la réalité (que vous verrez avecANALYZE), le planificateur peut avoir choisi un mauvais plan. Cela arrive souvent quand les statistiques sur les tables sont obsolètes (ANALYZE table_name;pour les mettre à jour). -
actual time=0.022..120.456(avecANALYZE) : Le temps réel en millisecondes pour exécuter ce nœud. C’est la métrique ultime. Le premier temps est pour récupérer la première ligne, le second pour toutes les lignes. -
Buffers: shared hit=5 read=1250(avecBUFFERS) : Montre l’usage du cache.shared hit= données lues depuis le cache en RAM (rapide).shared read= données lues depuis le disque (lent). Un grand nombre dereadindique que la requête est gourmande en I/O.
La Méthode Pas à Pas pour Optimiser avec EXPLAIN
-
Isoler la requête lente depuis vos logs d’application.
-
Lancer
EXPLAIN (ANALYZE, BUFFERS)sur cette requête dans votre client SQL (psql, Adminer, etc.). -
Identifier le « goulot » (bottleneck) :
-
Cherchez l’opération avec le plus grand
actual time. -
Regardez si c’est un
Seq Scansur une grosse table. -
Vérifiez s’il y a un
Sortcoûteux ou une jointure inefficace.
-
-
Formuler une hypothèse : « Ce
Seq Scansurordersoù je filtre parcustomer_idaurait besoin d’un index. » -
Créer l’index et relancer
EXPLAIN. Vérifiez que leSeq Scanest remplacé par unIndex Scanet que les temps chutent. -
Toujours mesurer après coup dans l’application.
Les Pièges à Éviter
-
Trop d’index :
EXPLAINmontre les bénéfices, mais n’oubliez pas qu’un index ralentit lesINSERT,UPDATEetDELETE. Utilisez-le pour cibler les requêtes fréquentes et lentes. -
Statistiques obsolètes : Si les estimations (
rows) sont folles, lancezANALYZEsur la table concernée. -
Ne pas tester avec des données réalistes : Une requête rapide sur 100 lignes de test peut devenir un désastre sur 10 millions. Utilisez un jeu de données de production ou réaliste.
De l’Intuition à la Science
Avant EXPLAIN, l’optimisation SQL était de la devinette. Après EXPLAIN, c’est une science. Cet outil transforme une boîte noire en un processus transparent et analysable.
Prenez l’habitude de l’utiliser systématiquement pour toute nouvelle requête non-triviale ou pour tout ralentissement. La capacité à lire un plan d’exécution et à en déduire l’action corrective (souvent un index bien placé) est l’une des compétences les plus valorisantes et impactantes pour un développeur full-stack ou un DBA. Arrêtez de deviner, commencez à analyser.