0Pricing
Coding Interview Prep · Lezione

Leggere un piano EXPLAIN

Interpretazione dei tipi di scansione, dei metodi di join e delle stime dei costi in un piano di query.

Leggere un piano EXPLAIN è una lezione Coding Interview Prep gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Coding Interview Prep, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Coding Interview Prep include 4 lezioni in totale.

Perché gli intervistatori chiedono di usare EXPLAIN

Quando arriva a un colloquio per un ruolo senior, gli intervistatori smettono di chiedere scriva una query e iniziano a chiedere perché questa query è lenta. Lo strumento che risponde a questa domanda è EXPLAIN.

EXPLAIN mostra il piano di esecuzione del database: la strategia passo per passo che il pianificatore ha scelto per eseguire il codice SQL. Rivela quali tabelle vengono scansionate, in quale ordine vengono eseguiti i join e quanto è approssimativamente costosa ogni operazione.

Saper leggere un piano dimostra di comprendere il motore, non soltanto la sintassi. È proprio questo il criterio che gli intervistatori usano per distinguere un profilo di livello intermedio da uno senior.

EXPLAIN ed EXPLAIN ANALYZE

Esistono due varianti e gli intervistatori amano verificare che sappia distinguerle.

  • EXPLAIN mostra il piano stimato dal pianificatore senza eseguire la query. È rapido e sicuro.
  • EXPLAIN ANALYZE esegue realmente la query e riporta i conteggi effettivi delle righe e i tempi reali, insieme alle stime.

L'informazione più utile consiste nel confrontare le righe stimate con quelle effettive. Una grande discrepanza indica che il pianificatore dispone di statistiche inaccurate e probabilmente sta facendo una scelta non ottimale.

Attenzione: EXPLAIN ANALYZE esegue davvero la query, quindi eseguirà qualsiasi INSERT o UPDATE, a meno che non venga racchiusa in una transazione di cui viene eseguito il rollback.

EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;

Come leggere l'albero

Un piano è un albero, non un elenco. I nodi con la maggiore indentazione sono le foglie che vengono eseguite per prime; i risultati risalgono verso la radice, che produce l'output finale.

Lo legga dall'interno verso l'esterno: individui il nodo più profondo, perché è lì che inizia l'esecuzione. Ogni nodo padre consuma le righe prodotte dai nodi figli.

Durante un colloquio, lo descriva in questo modo: prima eseguiamo la scansione di questa tabella, quelle righe alimentano questo join, il join alimenta l'ordinamento e l'ordinamento alimenta il limite. È proprio questa descrizione dal basso verso l'alto che vogliono sentire.

Anatomia di un nodo del piano

Ogni nodo di un piano Postgres contiene gli stessi numeri principali:

  • cost=0.00..35.50 costo di avvio..costo totale in unità arbitrarie del planner
  • rows=1000 numero stimato di righe prodotte
  • width=64 dimensione media stimata di una riga in byte

Il primo cost è il costo di avvio (il lavoro eseguito prima che venga restituita la prima riga, ad esempio la costruzione di una tabella hash). Il secondo è il costo totale per restituire tutte le righe. Un costo totale più elevato indica una maggiore spesa relativa secondo la stima del planner.

Seq Scan on orders  (cost=0.00..35.50 rows=1000 width=64)

Un esempio svolto

Consideri una semplice query con filtro. Il piano seguente racconta tutto in una sola riga.

Si tratta di una Seq Scan (lettura completa della tabella) su orders, che applica il filtro status = 'shipped'. Il planner stima 1000 righe corrispondenti.

Se orders contiene 10 milioni di righe e solo 1000 corrispondono, in un colloquio ci si aspetta che dica: una scansione sequenziale in questo caso è inefficiente; un indice su status (o su una colonna più selettiva) ci permetterebbe di evitare la lettura dell'intera tabella.

EXPLAIN SELECT * FROM orders WHERE status = 'shipped';

Seq Scan on orders  (cost=0.00..18334.00 rows=1000 width=64)
  Filter: (status = 'shipped'::text)

Righe stimate e righe effettive

Con EXPLAIN ANALYZE si ottengono anche i numeri effettivi tra parentesi.

Osservi l'esempio: il planner aveva stimato 1000 righe, ma ne ha ottenute effettivamente 480000. Si tratta di una sottostima di 480 volte. Il planner ha scelto la strategia ipotizzando poche righe, quindi la sua scelta è probabilmente sbagliata per i dati reali.

Nei colloqui, questa differenza costituisce la diagnosi principale: le statistiche sono obsolete; esegua ANALYZE sulla tabella, dopodiché il planner probabilmente sceglierà un piano migliore.

Seq Scan on orders
  (cost=0.00..18334.00 rows=1000 width=64)
  (actual time=0.02..210.4 rows=480000 loops=1)

Che cosa significa loops=N

Il valore di loops è più importante di quanto molti candidati si aspettino. Indica il numero di volte in cui un nodo è stato eseguito.

Questo valore compare sul lato interno di un nested loop join: il nodo interno viene eseguito una volta per ogni riga esterna. Se loops=480000, quel passaggio interno è stato eseguito 480 mila volte.

Importante: il tempo per riga e il numero di righe visualizzati sono per ciclo. Per ottenere il totale effettivo, deve moltiplicarli per loops. Un nodo che sembra economico con 0.004ms per ciclo arriva a quasi 2 secondi nell'arco di 480000 cicli.

Index Scan using idx_cust on orders
  (actual time=0.003..0.004 rows=1 loops=480000)

Il cost è relativo, non espresso in millisecondi

Una trappola frequente: i candidati leggono cost=18334 e dicono ci vogliono 18 secondi. Sbagliato.

Il cost è espresso in unità arbitrarie del planner, calibrate in modo che una lettura sequenziale di pagina valga 1.0. È significativo solo per confrontare i piani tra loro, non come misura del tempo effettivo.

Per misurare il tempo reale servono EXPLAIN ANALYZE e i relativi valori di actual time, espressi in millisecondi. Lo dica chiaramente in un colloquio: dimostra che comprende davvero questa metrica.

Lettura di un piano di join

Questo è un piano su due tabelle. Lo legga dal basso verso l'alto.

Le prime due scansioni raccolgono le righe da orders e customers. Alimentano un Hash Join: un lato viene sottoposto a hashing, mentre l'altro cerca nella tabella hash. L'output del join alimenta poi il risultato finale.

Noti che l'indentazione mostra la struttura: entrambe le scansioni si trovano sotto l'Hash Join. L'intervistatore vuole che identifichi il metodo di join (in questo caso hash) e quale tabella viene usata per costruire la tabella hash (di solito quella più piccola).

Hash Join  (cost=30.0..520.0 rows=900 width=72)
  Hash Cond: (o.customer_id = c.id)
  ->  Seq Scan on orders o  (cost=0..400 rows=10000)
  ->  Hash  (cost=18..18 rows=500)
        ->  Seq Scan on customers c  (cost=0..18 rows=500)

Segnali d'allarme da evidenziare

Alleni l'occhio a riconoscere questi segnali d'allarme in qualsiasi piano:

  • Seq Scan su una tabella enorme con un filtro selettivo: un indice potrebbe essere utile.
  • Righe stimate molto diverse da quelle effettive: statistiche obsolete.
  • Nested Loop con un numero elevato di loops su una tabella grande: spesso manca un indice sulla chiave di join interna.
  • Sort o Hash che riversano dati su disco (indicato dall'uso di Disk): work_mem è troppo piccolo.
  • Rows Removed by Filter molto elevato: è stata letta e scartata la maggior parte della tabella.

Formati di output e BUFFERS

I piani sono disponibili in diversi formati. Il formato predefinito TEXT è quello che si legge ad alta voce nei colloqui. È però possibile richiedere anche un output strutturato.

EXPLAIN (FORMAT JSON) o FORMAT YAML producono piani leggibili dalle macchine, che possono essere analizzati da strumenti e dashboard. Raramente è necessario leggerli manualmente, ma sapere che esistono è un dettaglio apprezzato da un senior.

Aggiunga le opzioni tra parentesi: EXPLAIN (ANALYZE, BUFFERS). L'opzione BUFFERS indica gli accessi soddisfatti dalla cache rispetto alle letture da disco, un'informazione preziosa per diagnosticare query limitate dall'I/O.

EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE customer_id = 42;

Verifica rapida

Un intervistatore Le mostra un nodo EXPLAIN ANALYZE con rows=1000 nella sezione dei costi, ma con actual ... rows=480000. Qual è la diagnosi più probabile?

Riepilogo

Ora sa leggere un piano come un senior:

  • EXPLAIN esegue stime, mentre EXPLAIN ANALYZE esegue la query e misura i risultati.
  • Legga l'albero dal basso verso l'alto: le foglie vengono eseguite per prime e la radice produce l'output.
  • Ogni nodo mostra il cost (unità relative), rows e width; actual time è il valore reale in millisecondi.
  • loops moltiplica i valori per ciclo: presti attenzione ai nested loop.
  • La differenza tra righe stimate ed effettive è il principale segnale diagnostico.

Descriva il piano ad alta voce ed evidenzi i segnali d'allarme: è questo il comportamento che fa la differenza in un colloquio.

Domande Frequenti

La lezione «Leggere un piano EXPLAIN» è gratuita?

Sì — il testo completo di «Leggere un piano EXPLAIN» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Coding Interview Prep, passa a CoddyKit PRO. Il corso Coding Interview Prep include 4 lezioni in totale.

Cosa imparerò in «Leggere un piano EXPLAIN»?

Interpretazione dei tipi di scansione, dei metodi di join e delle stime dei costi in un piano di query. Eserciti Coding Interview Prep con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Coding Interview Prep?

Non è richiesta alcuna esperienza precedente. Coding Interview Prep su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Leggere un piano EXPLAIN»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Coding Interview Prep?

Sì. Ogni lezione Coding Interview Prep include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Leggere un piano EXPLAIN
  2. Seq Scan, Index Scan e Index-Only
  3. Algoritmi di join: Nested Loop, Hash, Merge
  4. Individuare e risolvere le query lente
← Torna a Coding Interview Prep