Sans index, la base lit chaque ligne pour répondre à une question. Avec le bon, elle saute droit à la réponse. Sur une grande table, l'écart va de quelques secondes à quelques microsecondes — et le mauvais index est pire que pas d'index du tout, car il coûte à l'écriture et n'apporte rien.
Indexez ce sur quoi vous FILTREZ
La clause WHERE, puis ORDER BY, puis les colonnes de jointure. Pas ce que vous mettez dans le SELECT — ce n'est pas ce que la recherche utilise.
SELECT * FROM orders WHERE customer_id = 42 ORDER BY created_at DESC;
CREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at);
L'ordre compte dans un index composite
Un index composite s'utilise de gauche à droite, comme un annuaire trié par nom puis par prénom. Trié ainsi, vous trouvez tous les Ali ; vous ne trouvez pas tous ceux dont le prénom est Mohamed.
(customer_id, created_at)sert un filtre sur customer_id, et un filtre sur les deux.- Il ne sert PAS un filtre sur created_at seul.
- Mettez en premier la colonne sur laquelle vous filtrez exactement, et en second l'intervalle ou le tri.
Prouvez qu'il est utilisé
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;
type: ref ou const signifie que l'index est utilisé. type: ALL signifie un balayage complet, donc un index ignoré — le plus souvent parce que la colonne est enveloppée dans une fonction.
WHERE DATE(created_at) = "2026-01-01" ne peut pas utiliser d'index sur created_at : la fonction doit d'abord s'exécuter sur chaque ligne. Écrivez-le plutôt comme un intervalle : created_at >= "2026-01-01" AND created_at < "2026-01-02".Pourquoi ne pas tout indexer
- Chaque index est mis à jour à chaque INSERT, UPDATE et DELETE. Dix index rendent les écritures plusieurs fois plus lentes.
- Ils prennent du disque, parfois plus que la table elle-même.
- Le planificateur a plus de choix et prend parfois le moins bon.