Aller au contenu principal

Plans d’exécution (EXPLAIN)

Progression

#Plans d’exécution (EXPLAIN)

Comprendre comment le moteur exécute une requête vous aide à poser les bons index et à réécrire des requêtes coûteuses. Un plan décrit l’ordre des opérations (scan, filtre, jointure, agrégat) et la stratégie choisie (index lookup, hash join, nested loops, tri).

#Lire un plan — notions clés

#Plan interactif (heuristique)

Filter
Join
Scan A
Scan B
Plan heuristique simplifié: Scan/Join → Filter → Aggregate
  • Node: une opération (Scan, Index Scan, Join, Aggregate).
  • Coût estimé: combine cardinalité (lignes attendues) et coût I/O/CPU.
  • Ordre: l’arbre se lit de bas en haut; chaque nœud consomme ses enfants.

Exemple (pseudo‑plan):

bg-[rgba(var(--code-inline-bg),0.5)] text-[rgb(var(--fg))] px-1 roundedbg-[rgba(var(--code-inline-bg),0.5)] text-[rgb(var(--fg))] px-1 rounded
1Aggregate (sum)2  -> Hash Join (users.id = orders.user_id)3       -> Seq Scan users4       -> Index Scan orders(user_id)

Interprétation: on scanne users, on cherche les orders via index, on joint en hash, puis on agrège.

#Animation: pipeline d’exécution

Parser
Analyse et construction AST
Rewriter
Simplifications, pushdown des prédicats
Planner
Choix des index, type de join
Executor
Scans/joins/agrégats en flux
Résultat
Retour des lignes/agrégats

#Ajuster la requête

  • Filtrer tôt: pousser les WHERE en amont réduit les lignes intermédiaires.
  • Index alignés: index sur colonnes filtrées/jointes dans le bon ordre (égalité → plage → tri).
  • SARGability: éviter les fonctions côté colonne; préférer des bornes.

#Atelier rapide

Sur une base jouet: users(id, name), orders(id, user_id, amount).

  1. Sans index: select sum(amount) from orders join users using(user_id) where users.name like 'A%'.
  2. Créez index (user_id) sur orders, index (name) sur users.
  3. Réexécutez; discutez de l’impact attendu du plan.

#Bonnes pratiques

  • Mesurez avant/après (temps, plan, lignes retournées).
  • Gardez des index minimalistes mais efficaces (supprimez les orphelins).
  • Analysez les stats (ANALYZE) quand le moteur en dépend.

#Mini‑exercice: prédire un plan

Base: orders(user_id, created_at, status, amount), index existants: (user_id), (created_at), aucun index composite.

Question: pour select sum(amount) from orders where user_id=42 and created_at>=date('now','-7 days'), quel plan attendez‑vous sur un moteur classique (SQLite/Postgres) ?

Pistes:

  • Sans index composite (user_id, created_at), le plan peut choisir un index sur user_id puis filtrer par date (ou l’inverse) selon la sélectivité.
  • Un index composite aligné sur les prédicats (égalité puis plage) améliore la sélectivité: (user_id, created_at).