Repérer et corriger les requêtes lentes
Une liste de contrôle pour répondre à la question d’entretien « cette requête est lente, corrigez-la »
Repérer et corriger les requêtes lentes est une leçon Coding Interview Prep gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Coding Interview Prep, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Coding Interview Prep comprend 4 leçons au total.
La consigne « Cette requête est lente, corrigez-la »
Il s'agit de la consigne d'entretien finale : le recruteur vous présente une requête lente et un plan EXPLAIN ANALYZE, puis vous demande de la diagnostiquer. Il évalue une méthode, et non des astuces mémorisées.
Une réponse solide suit à voix haute une liste de contrôle : mesurer, lire le plan, repérer le coût dominant, formuler une hypothèse, proposer une correction, puis vérifier. Cette leçon construit cette liste étape par étape.
Restez méthodique et explicitez votre raisonnement : c'est ce qui vous permet d'obtenir une évaluation senior.
Étape 1 : mesurer avec EXPLAIN ANALYZE
Ne vous fiez jamais au SQL seul. Obtenez le plan réel avec EXPLAIN (ANALYZE, BUFFERS).
ANALYZE fournit les temps réels et le nombre réel de lignes ; BUFFERS indique si vous utilisez le cache ou si vous lisez depuis le disque. Ensemble, ces informations vous indiquent si la requête est limitée par le CPU, par les entrées-sorties ou si elle effectue simplement trop de travail.
Exécutez-la plusieurs fois ; la première exécution peut subir la pénalité d'un cache froid, ce qui fausse la mesure du temps.
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.created_at >= '2026-01-01';Étape 2 : repérer le nœud dominant
Ne parcourez pas le plan de haut en bas au hasard. Repérez le nœud où le plus de temps est réellement consommé.
Calculez le temps propre de chaque nœud : son actual time total moins le temps de ses enfants, multiplié par loops. Le nœud qui représente la plus grande part est votre cible ; tout le reste est secondaire.
Lors d'un entretien, dites : 80 % du temps d'exécution se trouve dans ce balayage séquentiel, c'est donc là que je me concentre. Optimiser quoi que ce soit d'autre serait un effort inutile.
Étape 3 : comparer les valeurs estimées aux valeurs réelles
Sur le nœud dominant, comparez le nombre de lignes estimé au nombre de lignes réel. Un écart important signifie que le planificateur avance à l'aveugle et a probablement choisi un mauvais plan, avec un algorithme de jointure ou une méthode d'accès inadapté.
L'exemple montre une sous-estimation d'un facteur 1000. Avant de revoir la conception, actualisez les statistiques : cette simple commande corrige souvent le plan gratuitement.
ANALYZE recalcule les statistiques des colonnes ; VACUUM ANALYZE nettoie également les tuples obsolètes et met à jour la carte de visibilité.
-- estimate rows=100, actual rows=120000 -> stale stats
ANALYZE orders;
-- or, for bloated tables:
VACUUM ANALYZE orders;Cause fréquente : une fonction sur une colonne indexée
Le problème corrigeable le plus fréquent est le suivant : une fonction ou une conversion enveloppe la colonne dans WHERE, de sorte que l'index ne peut pas être utilisé et que le moteur effectue un balayage séquentiel.
L'exemple impose un parcours complet, car DATE() est appliquée à chaque ligne. Réécrivez la condition sous forme de prédicat d'intervalle portant directement sur la colonne, afin de permettre l'utilisation de l'index, et l'index sur created_at devient utilisable.
La même idée s'applique à WHERE lower(email)=... : stockez des données normalisées, interrogez directement la colonne ou créez un index d'expression.
-- Not sargable: index unusable
WHERE DATE(created_at) = '2026-01-01'
-- Sargable: range over the bare column
WHERE created_at >= '2026-01-01'
AND created_at < '2026-01-02'Cause fréquente : index manquant
Si le nœud dominant est un balayage séquentiel avec un filtre très sélectif, ou une boucle imbriquée dont la valeur de loops est très élevée sur une clé interne non indexée, la solution est généralement d'ajouter un index.
Ajoutez un index sur la colonne filtrée ou jointe. L'exemple en crée un sur customer_id, afin que la jointure puisse passer de balayages séquentiels à des balayages d'index ; le planificateur pourra alors choisir un plan bien moins coûteux.
Vérifiez le résultat en réexécutant EXPLAIN ANALYZE : ne supposez pas que l'index a été utile.
CREATE INDEX idx_orders_customer
ON orders (customer_id);Cause fréquente : SELECT * et lignes larges
SELECT * récupère toutes les colonnes depuis le disque et les transfère sur le réseau, et empêche les balayages utilisant uniquement l'index, car celui-ci contient rarement toutes les colonnes.
Ne sélectionnez que les colonnes dont vous avez besoin. Cela réduit la largeur des lignes, diminue les entrées-sorties et peut permettre un balayage couvert utilisant uniquement l'index.
Un recruteur qui glisse SELECT * dans l'exemple veut que vous le remarquiez. Réduire la liste des colonnes constitue souvent un gain rapide et réel sur les tables larges.
-- Before
SELECT * FROM orders WHERE customer_id = 42;
-- After: only needed columns (may enable index-only scan)
SELECT order_id, amount FROM orders WHERE customer_id = 42;Cause fréquente : écriture temporaire sur le disque
Si un nœud Sort ou Hash signale une utilisation du disque (Sort Method: external merge Disk: 25000kB ou Batches: > 1), l'opération a dépassé work_mem et écrit des données sur le disque.
Possibilités : augmenter work_mem pour la session, réduire le nombre de lignes qui atteignent le tri ou le hachage en filtrant plus tôt, ou ajouter un index qui fournit l'ordre trié afin de supprimer complètement l'étape de tri.
Il s'agit d'un diagnostic précis, de niveau senior, que les recruteurs apprécient.
Sort (actual rows=2000000 loops=1)
Sort Key: o.amount
Sort Method: external merge Disk: 25000kBCause fréquente : récupération de trop nombreuses lignes
Surveillez la présence de Rows Removed by Filter: 9500000. La requête a lu dix millions de lignes et en a éliminé presque toutes : c'est un gaspillage classique de travail.
Solutions : ajoutez un index afin que le filtre soit appliqué pendant l'accès, et non après ; rendez le prédicat plus sélectif ; ou poussez le filtrage plus tôt dans la requête afin que moins de lignes remontent dans l'arbre.
Le principe est simple : effectuez le moins de travail possible et filtrez aussi tôt et aussi efficacement que possible.
Seq Scan on events
Filter: (event_type = 'purchase')
Rows Removed by Filter: 9500000La liste de contrôle du diagnostic
Récitez cette liste lors de l'entretien et vous ne vous égarerez pas :
- Mesurez avec
EXPLAIN (ANALYZE, BUFFERS). - Repérez le nœud qui consomme le plus de temps.
- Comparez le nombre de lignes estimé au nombre réel et corrigez d'abord les statistiques obsolètes.
- Vérifiez l'indexabilité et retirez les fonctions des colonnes filtrées.
- Indexez les filtres sélectifs et les clés de jointure.
- Réduisez le nombre de colonnes et évitez
SELECT *. - Surveillez les écritures temporaires sur le disque et la récupération excessive de lignes.
- Vérifiez en réexécutant le plan.
Mise en pratique
Parcourez à voix haute un exemple complet. Le plan affiche un Seq Scan sur une table orders de 50 millions de lignes, avec le filtre customer_id = 42 et Rows Removed by Filter proche de 50 millions, tandis que l’estimation correspond approximativement aux valeurs réelles.
Diagnostic : filtre sélectif, aucun index, le coût dominant est le balayage. Correction : CREATE INDEX ON orders(customer_id). Relancez la requête : le plan bascule vers un Index Scan et le temps passe de plusieurs secondes à moins d’une milliseconde.
Cette boucle mesurer-diagnostiquer-corriger-vérifier constitue le modèle de réponse à toute question sur une requête lente.
CREATE INDEX idx_orders_customer ON orders (customer_id);
EXPLAIN (ANALYZE, BUFFERS)
SELECT order_id, amount FROM orders WHERE customer_id = 42;Vérification rapide
Une requête applique le filtre WHERE YEAR(order_date) = 2026 et le plan affiche un balayage complet Seq Scan malgré l’existence d’un index B-tree sur order_date. Quelle est la meilleure première correction ?
Récapitulatif
Vous disposez maintenant d’une méthode reproductible pour répondre aux questions sur les requêtes lentes :
- Commencez toujours par mesurer avec
EXPLAIN (ANALYZE, BUFFERS)et concentrez-vous sur le nœud dominant. - Corrigez d’abord les statistiques obsolètes lorsque les estimations et les valeurs réelles divergent.
- Rendez les prédicats compatibles avec une recherche par index, ajoutez des index pour les filtres sélectifs et les clés de jointure, et réduisez
SELECT *. - Traitez les débordements sur disque et la récupération excessive de données, puis vérifiez le nouveau plan.
Énoncez la liste de vérifications, proposez une modification concrète et relancez le plan pour la démontrer : c’est la réponse attendue d’un ingénieur expérimenté.
Apprends Coding Interview Prep avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 90
- Leçons
- 360
Questions Fréquemment Posées
La leçon « Repérer et corriger les requêtes lentes » est-elle gratuite ?
Oui — le texte complet de « Repérer et corriger les requêtes lentes » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Coding Interview Prep, passe à CoddyKit PRO. Le cours Coding Interview Prep comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Repérer et corriger les requêtes lentes » ?
Une liste de contrôle pour répondre à la question d’entretien « cette requête est lente, corrigez-la » Tu pratiques Coding Interview Prep avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Coding Interview Prep ?
Aucune expérience préalable n'est requise. Coding Interview Prep sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Repérer et corriger les requêtes lentes » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Coding Interview Prep ?
Oui. Chaque leçon Coding Interview Prep inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Lire un plan EXPLAIN
- Parcours séquentiel, parcours par index et parcours par index seul
- Algorithmes de jointure : boucle imbriquée, hachage, fusion
- Repérer et corriger les requêtes lentes