Commencez par le plan de requête, puis corrigez le coût le plus élevé. Utilisez / pour voir ce que la base de données fait réellement, ajoutez les bons , éliminez les requêtes , et sélectionnez uniquement les données dont vous avez besoin.
Commencez par le plan de requête, puis corrigez le coût le plus élevé. Utilisez / pour voir ce que la base de données fait réellement, ajoutez les bons , éliminez les requêtes , et sélectionnez uniquement les données dont vous avez besoin.
EXPLAINEXPLAIN ANALYZEEXPLAIN ANALYZE affiche le plan d'exécution et les timings réels. Un Seq Scan sur une grande table est le signal d'alerte classique :
EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;
-- Seq Scan on orders (cost=0.00..18500 rows=120)
-- Filter: (customer_id = 42)
-- rows removed by filter: 999880 ← scanned the whole table!
Un index transforme un scan complet en recherche rapide :
CREATE INDEX idx_orders_customer ON orders (customer_id);
-- Now: Index Scan using idx_orders_customer (cost=0.42..8.5 rows=120)
-- 1,000,000-row scan → ~120-row lookup
Les index ont un coût sur les écritures : chaque INSERT/UPDATE doit aussi mettre à jour l'index, donc indexez les colonnes sur lesquelles vous filtrez/joignez/triez — pas chaque colonne. Un index composite (customer_id, created_at) répond à WHERE customer_id = ? ORDER BY created_at en une seule structure.
Le problème N+1 — une requête pour une liste, puis une par ligne — est une cause majeure de lenteur. Remplacez-le par un chargement eager, un JOIN, ou un IN (...) par lot :
-- N+1: 1 + 100 queries
SELECT * FROM orders; -- then per order: SELECT * FROM users WHERE id = ?
-- Fixed: one JOIN, only needed columns
SELECT o.id, o.total, u.name
FROM orders o JOIN users u ON u.id = o.user_id;
Aussi, sélectionnez uniquement les colonnes nécessaires (évitez SELECT *) et paginéz avec LIMIT/keyset pagination pour ne jamais charger des millions de lignes.
La base de données est le goulot d'étranglement le plus courant. Lire le plan vous dit pourquoi une requête est lente au lieu de deviner ; le bon index, la suppression de N+1 et la réduction de l'ensemble de résultats transforment régulièrement les requêtes de plusieurs secondes en millisecondes — sans escalader le matériel.