PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Cosa mi dice esattamente PostgreSQL?

La parte che ho sempre trovato confuso è il costo di avvio rispetto al costo totale. Lo cerco su Google ogni volta che me ne dimentico, il che mi riporta qui, il che non spiega la differenza, motivo per cui sto scrivendo questa risposta. Questo è ciò che ho raccolto dal EXPLAIN di Postgres documentazione, spiegato come ho capito.

Ecco un esempio da un'applicazione che gestisce un forum:

EXPLAIN SELECT * FROM post LIMIT 50;

Limit  (cost=0.00..3.39 rows=50 width=422)
  ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

Ecco la spiegazione grafica di PgAdmin:

(Quando utilizzi PgAdmin, puoi puntare il mouse su un componente per leggere i dettagli del costo.)

Il costo è rappresentato come una tupla, ad es. il costo del LIMIT è cost=0.00..3.39 e il costo della scansione sequenziale di post è cost=0.00..15629.12 . Il primo numero nella tupla è il costo di avvio e il secondo numero è il costo totale . Perché ho usato EXPLAIN e non EXPLAIN ANALYZE , questi costi sono stime, non misure effettive.

  • Costo di avvio è un concetto complicato. Non rappresenta solo la quantità di tempo prima che quel componente si avvii . Rappresenta la quantità di tempo tra l'inizio dell'esecuzione del componente (lettura dei dati) e il momento in cui il componente emette la sua prima riga .
  • Costo totale è l'intero tempo di esecuzione del componente, da quando inizia a leggere i dati a quando finisce di scrivere il suo output.

Come complicazione, i costi di ciascun nodo "principale" includono i costi dei suoi nodi figli. Nella rappresentazione testuale, l'albero è rappresentato da un rientro, ad es. LIMIT è un nodo padre e Seq Scan è suo figlio. Nella rappresentazione PgAdmin, le frecce puntano dal figlio al genitore, la direzione del flusso di dati, il che potrebbe essere controintuitivo se si ha familiarità con la teoria dei grafi.

La documentazione dice che i costi sono comprensivi di tutti i nodi figli, ma si noti che il costo totale del genitore 3.39 è molto inferiore al costo totale del suo figlio 15629.12 . Il costo totale non è compreso perché un componente come LIMIT non ha bisogno di elaborare il suo intero input. Vedi EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; esempio in Postgres EXPLAIN documentazione.

Nell'esempio sopra, il tempo di avvio è zero per entrambi i componenti, perché nessuno dei componenti deve eseguire alcuna elaborazione prima di iniziare a scrivere righe:una scansione sequenziale legge la prima riga della tabella e la emette. Il LIMIT legge la sua prima riga e poi la emette.

Quando un componente dovrebbe eseguire molte elaborazioni prima di poter iniziare a produrre righe? Ci sono molte possibili ragioni, ma diamo un'occhiata a un chiaro esempio. Ecco la stessa query di prima ma ora contenente un ORDER BY clausola:

EXPLAIN SELECT * FROM post ORDER BY body LIMIT 50;

Limit  (cost=23283.24..23283.37 rows=50 width=422)
  ->  Sort  (cost=23283.24..23859.27 rows=230412 width=422)
        Sort Key: body
        ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

E graficamente:

Ancora una volta, la scansione sequenziale su post non ha alcun costo di avvio:avvia immediatamente l'output delle righe. Ma l'ordinamento ha un costo di avvio significativo 23283.24 perché deve ordinare l'intera tabella prima di poter produrre anche una singola riga . Il costo totale dell'ordinamento 23859.27 è solo leggermente superiore al costo di avvio, a dimostrazione del fatto che una volta che l'intero set di dati è stato ordinato, i dati ordinati possono essere emessi molto rapidamente.

Si noti che il tempo di avvio di LIMIT 23283.24 è esattamente uguale al tempo di avvio dell'ordinamento. Questo non è perché LIMIT di per sé ha un tempo di avvio elevato. In realtà ha un tempo di avvio zero da solo, ma EXPLAIN arrotola tutti i costi figlio per ciascun genitore, quindi il LIMIT tempo di avvio include la somma dei tempi di avvio dei suoi figli.

Questo cumulo di costi può rendere difficile la comprensione del costo di esecuzione di ogni singolo componente. Ad esempio, il nostro LIMIT ha zero tempi di avvio, ma non è ovvio a prima vista. Per questo motivo, molte altre persone si sono collegate a spiegare.depesz.com, uno strumento creato da Hubert Lubaczewski (alias depesz) che aiuta a capire EXPLAIN tra l'altro sottraendo i costi dei figli dai costi dei genitori. Menziona alcune altre complessità in un breve post sul blog sul suo strumento.