Ce que fait cet outil
L'EXPLAIN ANALYZE de PostgreSQL vous indique exactement comment une requête a été exécutée — mais la sortie brute est réputée difficile à lire. Les durées sont inclusives (le temps de chaque nœud contient celui de tous ses enfants), les nombres de lignes sont moyennés par boucle, et le véritable goulot d'étranglement est souvent enfoui à trois niveaux de profondeur dans l'arbre.
Ce visualiseur parse le plan et affiche, pour chaque nœud :
- Le temps exclusif — le temps passé dans le nœud lui-même, calculé comme son temps total (× loops) moins le temps de ses enfants, avec une barre colorée proportionnelle à sa part dans l'ensemble de la requête.
- Les lignes estimées vs réelles — l'estimation de lignes du planificateur à côté de ce qui est réellement sorti, avec le facteur d'erreur d'estimation lorsqu'elles divergent.
- Les détails des buffers, filtres, tris et hachages lorsqu'ils sont présents dans le plan.
Comment obtenir un plan
Exécutez votre requête avec :
EXPLAIN (ANALYZE, BUFFERS)
SELECT ... your query ...;
et collez le résultat ci-dessus — le format texte par défaut et FORMAT JSON sont tous deux pris en charge. BUFFERS est optionnel mais recommandé — il montre combien d'E/S chaque nœud a effectuées. Vous pouvez coller directement depuis psql : l'en-tête QUERY PLAN et les caractères de continuation de ligne + sont nettoyés automatiquement.
⚠️ EXPLAIN ANALYZE exécute réellement la requête. Pour un INSERT/UPDATE/DELETE, encadrez-le dans BEGIN; ... ROLLBACK;.
Partager un plan
Copier le lien de partage encode tout le plan, compressé, dans l'URL elle-même (la partie après #). Rien n'est envoyé nulle part — le fragment n'atteint même jamais notre serveur web — donc la promesse « zéro envoi » tient. Le revers mérite d'être dit explicitement : le lien contient le plan, donc quiconque à qui vous l'envoyez peut y lire les noms de tables, les valeurs de filtre et les nombres de lignes. Les très gros plans produisent des URL très longues ; certains outils de chat les tronquent, auquel cas le destinataire obtient une erreur claire plutôt qu'un plan erroné.
Avertissements que cet outil détecte
- Estimation de lignes erronée de plus de 10× — le planificateur attendait un nombre de lignes très différent de ce qu'il a obtenu. Les mauvaises estimations se propagent en mauvaises stratégies de jointure. Correctifs typiques : lancer
ANALYZEsur la table, augmenter la cible de statistiques de la colonne, ou ajouter des statistiques étendues pour les colonnes corrélées. - Parcours séquentiel sur de nombreuses lignes avec un filtre — l'exécuteur a lu toute la table pour n'en garder qu'une partie. Souvent le signe qu'un index aiderait.
- Tri qui déborde sur disque —
Sort Method: external mergesignifie que le tri n'a pas tenu danswork_memet a utilisé des fichiers temporaires. - Hachage qui déborde sur disque — un nœud Hash utilisant plus d'un batch a dû écrire des partitions sur disque ; la table de hachage n'a pas tenu dans
work_mem. - Boucle imbriquée coûteuse — le côté interne d'un Nested Loop a été exécuté de nombreuses fois et représente une part significative du temps d'exécution total.
- Beaucoup de lignes retirées par un filtre — le nœud a produit bien moins de lignes qu'il n'a dû en examiner, suggérant un index manquant ou peu sélectif.
- Nœud jamais exécuté est également signalé (loops = 0) afin que les nœuds à temps nul ne perturbent pas la lecture.
Lire le flame graph et l'arbre
Le flame graph en haut, c'est toute la requête d'un coup d'œil : chaque barre est un nœud du plan, sa largeur est le temps total passé dedans (enfants inclus) et sa couleur indique quelle part du temps de la requête correspond au travail propre du nœud — vert pour peu coûteux, rouge pour chaud. Une large barre rouge tout en bas est votre goulot d'étranglement ; cliquez dessus pour sauter au nœud correspondant dans l'arbre.
Dans l'arbre, l'exécution commence aux feuilles (les parcours) et remonte vers la racine. La barre horizontale sur chaque nœud est sa part de temps exclusif : une barre rouge sur un Seq Scan feuille signifie que le temps est réellement passé à parcourir, pas dans la jointure au-dessus. Cliquez sur l'en-tête d'un nœud pour développer ses détails — coûts, nombres de lignes, conditions de filtre, utilisation des buffers — et utilisez Copier le résumé texte pour coller un rapport compact dans un ticket ou un chat.
Note sur les requêtes parallèles : l'attribution des durées entre les workers parallèles est une approximation — les enfants d'un nœud Gather rapportent les loops par worker, donc les temps exclusifs y sont à lire comme indicatifs.
