Cosa fa questo strumento
EXPLAIN ANALYZE di PostgreSQL ti dice esattamente come è stata eseguita una query — ma l'output grezzo è notoriamente difficile da leggere. I tempi sono inclusivi (il tempo di ogni nodo contiene quello di tutti i suoi figli), i conteggi delle righe sono mediati per loop e il vero collo di bottiglia è spesso sepolto tre livelli più in basso nell'albero.
Questo visualizzatore analizza il piano e mostra, per ogni nodo:
- Tempo esclusivo — il tempo trascorso nel nodo stesso, calcolato come tempo totale (× loop) meno il tempo dei suoi figli, con una barra colorata proporzionale alla sua quota sull'intera query.
- Righe stimate contro effettive — la stima delle righe del planner accanto a ciò che è realmente uscito, con il fattore di errore di stima quando divergono.
- Dettagli di buffer, filtri, sort e hash quando sono presenti nel piano.
Come ottenere un piano
Esegui la tua query con:
EXPLAIN (ANALYZE, BUFFERS)
SELECT ... your query ...;
e incolla il risultato qui sopra — sono supportati sia il formato testo predefinito sia FORMAT JSON. BUFFERS è facoltativo ma consigliato — mostra quanto I/O ha eseguito ciascun nodo. Puoi incollare direttamente da psql: l'intestazione QUERY PLAN e i caratteri di continuazione riga + vengono ripuliti automaticamente.
⚠️ EXPLAIN ANALYZE esegue realmente la query. Per un INSERT/UPDATE/DELETE, racchiudilo in BEGIN; ... ROLLBACK;.
Condividere un piano
Copia link di condivisione codifica l'intero piano, compresso, nell'URL stesso (la parte dopo #). Non viene caricato nulla da nessuna parte — il frammento non raggiunge nemmeno il nostro web server — quindi la promessa di zero upload resta valida. Il rovescio della medaglia va detto esplicitamente: il link contiene il piano, quindi chiunque tu lo mandi potrà leggere nomi di tabelle, valori dei filtri e conteggi delle righe. Piani molto grandi producono URL molto lunghi; alcuni strumenti di chat li troncano, nel qual caso il destinatario riceve un errore chiaro anziché un piano sbagliato.
Warning rilevati da questo strumento
- Stima delle righe sbagliata di oltre 10× — il planner si aspettava un numero di righe molto diverso da quello ottenuto. Le stime errate si propagano in strategie di join sbagliate. Rimedi tipici: eseguire
ANALYZEsulla tabella, aumentare lo statistics target della colonna o aggiungere statistiche estese per colonne correlate. - Scansione sequenziale su molte righe con un filtro — l'executor ha letto l'intera tabella per tenerne solo una parte. Spesso è segno che un indice aiuterebbe.
- Sort che spilla su disco —
Sort Method: external mergesignifica che il sort non è entrato inwork_meme ha usato file temporanei. - Hash che spilla su disco — un nodo Hash che usa più di un batch ha dovuto scrivere partizioni su disco; la tabella hash non è entrata in
work_mem. - Nested loop costoso — il lato interno di un Nested Loop è stato eseguito molte volte e rappresenta una quota significativa del tempo di esecuzione totale.
- Molte righe rimosse da un filtro — il nodo ha prodotto molte meno righe di quante ne ha dovute esaminare, il che suggerisce un indice mancante o poco selettivo.
- Nodo mai eseguito viene anch'esso segnalato (loops = 0) così che i nodi a tempo zero non confondano la lettura.
Leggere il flame graph e l'albero
Il flame graph in alto è l'intera query a colpo d'occhio: ogni barra è un nodo del piano, la sua larghezza è il tempo totale trascorso in esso (figli inclusi) e il suo colore indica quanta parte del tempo della query è lavoro proprio del nodo — verde per economico, rosso per caldo. Una barra rossa larga in profondità è il tuo collo di bottiglia; cliccala per saltare al nodo corrispondente nell'albero.
Nell'albero, l'esecuzione parte dalle foglie (le scansioni) e risale fino alla radice. La barra orizzontale su ogni nodo è la sua quota di tempo esclusivo: una barra rossa su una foglia Seq Scan significa che il tempo è speso davvero nella scansione, non nel join sopra di essa. Clicca l'intestazione di un nodo per espanderne i dettagli — costi, conteggi delle righe, condizioni di filtro, uso dei buffer — e usa Copia riepilogo testuale per incollare un report compatto in un ticket o in una chat.
Nota sulle query parallele: l'attribuzione dei tempi tra i worker paralleli è un'approssimazione — i figli di un nodo Gather riportano loop per worker, quindi i tempi esclusivi lì vanno letti come indicativi.
