0Pricing
Coding Interview Prep · Leçon

Parcours séquentiel, parcours par index et parcours par index seul

Pourquoi l’optimiseur choisit chacun d’eux et ce que cela vous apprend sur votre requête

Parcours séquentiel, parcours par index et parcours par index seul est une leçon Coding Interview Prep gratuite sur CoddyKit. Ceci est la leçon 2 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.

Trois façons de lire une table

Lorsque le planificateur a besoin de lignes provenant d’une table, il choisit l’une de trois méthodes d’accès, et les personnes qui vous interrogent s’attendent à ce que vous les nommiez toutes :

  • Analyse séquentielle : lire chaque ligne de la table du début à la fin.
  • Analyse par index : parcourir un index pour trouver les lignes correspondantes, puis récupérer chacune d’elles dans la table.
  • Analyse par index seul : répondre entièrement à partir de l’index sans accéder à la table.

Comprendre pourquoi le planificateur choisit chacune de ces méthodes est le cœur de cette leçon et une question incontournable pour un profil expérimenté.

Ce que fait une analyse séquentielle

Une analyse séquentielle lit les pages de la table l’une après l’autre et applique tout filtre à chaque ligne. Aucun index n’est consulté.

Cela semble mauvais, mais c’est souvent le bon choix. Les lectures séquentielles sont rapides sur disque (sans déplacements aléatoires) ; lorsqu’une requête renvoie une grande partie de la table, tout analyser est plus efficace que de parcourir un index des millions de fois.

L’exemple consiste à analyser orders et à conserver les lignes pour lesquelles amount > 100. Si la plupart des commandes dépassent 100, l’analyse séquentielle est le bon choix.

EXPLAIN SELECT * FROM orders WHERE amount > 100;

Seq Scan on orders  (cost=0.00..18334.00 rows=900000 width=64)
  Filter: (amount > 100)

Ce que fait une analyse par index

Une analyse par index utilise un arbre B pour accéder directement aux clés correspondantes, puis lit les lignes correspondantes dans le tas de la table.

Elle est particulièrement efficace lorsque le filtre est sélectif et ne renvoie qu’une petite partie de la table. Rechercher 5 lignes au moyen d’un index est plus efficace que d’en lire 10 millions.

Le plan indique le nom de l’index utilisé. Chaque correspondance coûte une recherche dans l’index et une récupération dans le tas (une lecture aléatoire) ; les analyses par index perdent donc leur avantage lorsqu’elles renvoient trop de lignes.

EXPLAIN SELECT * FROM orders WHERE customer_id = 42;

Index Scan using idx_orders_customer on orders
  (cost=0.42..38.50 rows=12 width=64)
  Index Cond: (customer_id = 42)

La sélectivité détermine le choix

Le concept central qui explique tout cela est la sélectivité : la proportion de lignes conservées par un prédicat.

  • Forte sélectivité (peu de lignes correspondent, comme avec un identifiant unique) : elle favorise une analyse par index.
  • Faible sélectivité (beaucoup de lignes correspondent, comme avec status IS NOT NULL) : elle favorise une analyse séquentielle.

Une règle empirique courante est qu’à partir du moment où une requête renvoie plus ou moins 5 à 10 % d’une table, le planificateur préfère souvent une analyse séquentielle, car les récupérations aléatoires dans le tas d’un index deviennent plus coûteuses que la lecture ordonnée de l’ensemble.

L’analyse par index seul

Une analyse par index seul est la plus rapide des trois. Si toutes les colonnes nécessaires à la requête sont déjà présentes dans l’index, le moteur n’accède jamais au tas de la table.

La requête d’exemple sélectionne uniquement customer_id et filtre sur cette colonne, tandis que l’index porte sur customer_id. Toutes les données nécessaires se trouvent dans l’index ; Postgres indique donc Analyse par index seul.

Cela évite les lectures aléatoires dans le tas qui ralentissent une analyse par index classique, ce qui constitue un gain considérable sur les tables larges.

EXPLAIN SELECT customer_id FROM orders WHERE customer_id = 42;

Index Only Scan using idx_orders_customer on orders
  (cost=0.42..8.44 rows=12 width=4)
  Index Cond: (customer_id = 42)

Le piège de la carte de visibilité

Les personnes qui vous interrogent apprécient beaucoup cette nuance. Une analyse par index seul doit tout de même confirmer que chaque ligne est visible pour votre transaction (MVCC), et l’index seul ne stocke pas les informations de visibilité.

Postgres utilise la carte de visibilité : si une page est marquée comme entièrement visible, le tas est ignoré ; sinon, la ligne du tas doit tout de même être récupérée. Le plan affiche Heap Fetches: N.

C’est pourquoi une table récemment mise à jour peut afficher de nombreuses récupérations dans le tas et ralentir les analyses par index seul, jusqu’à ce que VACUUM actualise la carte de visibilité.

Index Only Scan using idx_orders_customer on orders
  (actual time=0.01..0.03 rows=12 loops=1)
  Heap Fetches: 0

Analyses par bitmap : le compromis

Une quatrième méthode apparaît souvent : l’analyse du tas par bitmap. Le planificateur la choisit lorsqu’un prédicat correspond à davantage de lignes qu’une analyse par index classique ne le souhaite, mais à moins de lignes qu’une lecture complète de la table.

Il construit d’abord, à partir de l’index, un bitmap des emplacements des lignes correspondantes (analyse de l’index par bitmap), puis récupère les pages du tas dans l’ordre physique plutôt que dans un ordre aléatoire. Les récupérations ordonnées sont beaucoup moins coûteuses que les lectures dispersées d’une analyse par index classique.

Bitmap Heap Scan on orders  (cost=12.0..520.0 rows=8000)
  Recheck Cond: (status = 'pending')
  ->  Bitmap Index Scan on idx_orders_status
        (cost=0..12 rows=8000)
        Index Cond: (status = 'pending')

Pourquoi le planificateur a ignoré votre index

Une question classique en entretien : j’ai ajouté un index, mais le plan effectue toujours une analyse séquentielle ; pourquoi ? Voici les raisons courantes :

  • Le prédicat n’est pas sélectif : l’analyse séquentielle est réellement moins coûteuse.
  • Une fonction entoure la colonne : WHERE lower(email) = ... ne peut pas utiliser un index classique sur email.
  • Une incompatibilité de types impose une conversion implicite qui empêche l’utilisation de l’index.
  • Les statistiques sont obsolètes : exécutez ANALYZE.
  • La table est minuscule : analyser quelques pages est plus efficace que de subir le coût d’un index.

Diagnostic détaillé

Supposons que orders possède un index sur created_at, mais que cette requête effectue toujours une analyse séquentielle :

Le problème vient de DATE(created_at). Entourer la colonne d’une fonction signifie que l’index sur la valeur brute de created_at ne peut pas être utilisé. La solution consiste à réécrire la requête sous la forme d’un prédicat de plage qui laisse la colonne telle quelle, ou à créer un index d’expression sur DATE(created_at).

-- Slow: function on the indexed column
WHERE DATE(created_at) = '2026-01-01'

-- Fast: bare column, range uses the index
WHERE created_at >= '2026-01-01'
  AND created_at <  '2026-01-02'

Comparer les méthodes

Gardez cette comparaison à l’esprit pour l’entretien :

  • Analyse séquentielle : préférable lorsqu’une grande partie des lignes est renvoyée ; E/S séquentielles.
  • Analyse par index : préférable pour les recherches sélectives ; parcours de l’index suivi de récupérations aléatoires dans le tas.
  • Analyse du tas par bitmap : nombre de lignes correspondant situé entre les deux ; index vers bitmap, puis lectures ordonnées du tas.
  • Analyse par index seul : la plus rapide lorsque l’index couvre toutes les colonnes nécessaires et que les pages sont entièrement visibles.

Le planificateur choisit en fonction du coût estimé, principalement déterminé par la sélectivité et les statistiques.

Forcer un essai (et pourquoi pas en production)

Pour vérifier un point en développement, vous pouvez temporairement inciter le planificateur à changer de choix : SET enable_seqscan = off; le force à privilégier les index afin que vous puissiez comparer les plans.

Il s’agit d’une astuce de diagnostic, jamais d’une correction à appliquer en production. Mentionnez en entretien que les véritables solutions sont de meilleures statistiques, un index adapté ou la réécriture du prédicat, et non la désactivation globale des fonctionnalités du planificateur.

SET enable_seqscan = off;
EXPLAIN ANALYZE SELECT * FROM orders WHERE amount > 100;
SET enable_seqscan = on;

Vérification rapide

Une requête sélectionne uniquement email et filtre sur email, et un index B-tree existe sur email. Le plan affiche Index Only Scan. Pourquoi cette méthode est-elle plus rapide qu’une analyse par index classique ?

Récapitulatif

Points essentiels concernant les méthodes d’accès :

  • L’analyse séquentielle est la meilleure pour les requêtes à faible sélectivité ; l’analyse par index est la meilleure pour les requêtes sélectives.
  • L’analyse par index seul évite le tas lorsque l’index couvre toutes les colonnes nécessaires ; surveillez Heap Fetches et la carte de visibilité.
  • L’analyse du tas par bitmap constitue le compromis en récupérant les pages du tas dans l’ordre physique.
  • Le planificateur décide en fonction de la sélectivité et des statistiques ; les fonctions appliquées aux colonnes, les incompatibilités de types et les statistiques obsolètes expliquent pourquoi un index est ignoré.

Questions Fréquemment Posées

La leçon « Parcours séquentiel, parcours par index et parcours par index seul » est-elle gratuite ?

Oui — le texte complet de « Parcours séquentiel, parcours par index et parcours par index seul » 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 « Parcours séquentiel, parcours par index et parcours par index seul » ?

Pourquoi l’optimiseur choisit chacun d’eux et ce que cela vous apprend sur votre requête 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 2 sur 4.

Combien de temps prend la leçon « Parcours séquentiel, parcours par index et parcours par index seul » ?

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

  1. Lire un plan EXPLAIN
  2. Parcours séquentiel, parcours par index et parcours par index seul
  3. Algorithmes de jointure : boucle imbriquée, hachage, fusion
  4. Repérer et corriger les requêtes lentes
← Retour à Coding Interview Prep