Senza indice il database legge ogni riga per rispondere a una domanda. Con quello giusto salta dritto alla risposta. Su una tabella grande la differenza è fra secondi e microsecondi — e l'indice sbagliato è peggio di nessun indice, perché costa in scrittura e non dà nulla.
Indicizza ciò su cui FILTRI
La clausola WHERE, poi ORDER BY, poi le colonne di unione. Non ciò che metti nel SELECT: non è quello che usa la ricerca.
SELECT * FROM orders WHERE customer_id = 42 ORDER BY created_at DESC;
CREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at);
In un indice composto l'ordine conta
Un indice composto si usa da sinistra a destra, come un elenco telefonico ordinato per cognome e poi per nome. Ordinato così puoi trovare tutti quelli di cognome Ali; non puoi trovare tutti quelli che di nome fanno Mohamed.
(customer_id, created_at)serve un filtro su customer_id, e uno su entrambe.- NON serve un filtro sulla sola created_at.
- Metti per prima la colonna su cui filtri per uguaglianza, e per seconda l'intervallo o l'ordinamento.
Dimostra che venga davvero usato
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;
type: ref oppure const significa che l'indice è in uso. type: ALL significa scansione completa, cioè indice ignorato — di solito perché la colonna è avvolta in una funzione.
WHERE DATE(created_at) = "2026-01-01" non può usare un indice su created_at: la funzione deve prima girare su ogni riga. Scrivilo invece come intervallo: created_at >= "2026-01-01" AND created_at < "2026-01-02".Perché non indicizzare tutto
- Ogni indice viene aggiornato a ogni INSERT, UPDATE e DELETE. Dieci indici rendono le scritture parecchie volte più lente.
- Occupano disco, a volte più della tabella stessa.
- Il pianificatore ha più scelte e ogni tanto ne prende una peggiore.