Note dal lavoro · Backend
Leggere EXPLAIN in MySQL senza paura (e scegliere l’indice giusto)
Quando una query MySQL è lenta, EXPLAIN dice come il database intende eseguirla. All’inizio sembra una tabella criptica, ma poche colonne bastano per capire il problema.
EXPLAIN SELECT id, title
FROM posts
WHERE author_id = 12 AND status = 'published'
ORDER BY created_at DESC
LIMIT 20;
Le colonne che contano
type: come vengono lette le righe.ALLsignifica scansione completa della tabella (quasi sempre da evitare su tabelle grandi);ref,rangeeconstindicano che usa un indice.key: l’indice scelto davvero. Se èNULLnon ne usa nessuno.rows: una stima delle righe da leggere. Più è vicina al risultato atteso, meglio è.Extra: dettagli importanti.Using filesorteUsing temporarysegnalano ordinamenti o tabelle temporanee costosi;Using indexindica che bastano i dati dell’indice.
Perché un indice non viene usato
- Una funzione sulla colonna, come
WHERE DATE(created_at) = ..., impedisce di sfruttare l’indice: meglio un intervallo (created_at >= ... AND created_at < ...). LIKE '%testo'con il carattere jolly all’inizio non può usare un indice normale.- In un indice composto conta l’ordine delle colonne: viene sfruttato a partire dalla prima.
- Tipi diversi tra colonna e valore (una stringa confrontata con un numero) possono forzare conversioni.
Un indice composto per la query sopra
CREATE INDEX posts_author_status_created
ON posts (author_id, status, created_at);
Le colonne di uguaglianza (author_id, status) vengono per prime, quella usata per l’ordinamento (created_at) per ultima: così il database trova le righe giuste già in ordine, senza ordinarle a parte.
Misurare davvero
Da MySQL 8.0.18 esiste EXPLAIN ANALYZE, che esegue la query e mostra i tempi reali oltre alle stime. Confronta sempre prima e dopo con dati realistici: un indice in più rende più lente le scritture e occupa spazio, quindi va aggiunto per una ragione misurata.