Sei mesi fa
Negli ultimi mesi abbiamo fatto di lui
E ora siamo pronti a parlarti delle nuove funzionalità che puoi utilizzare.
Supporto per diversi formati di piano
Piano dal registro, insieme alla richiesta
Direttamente dalla console, selezioniamo l'intero blocco, partendo dalla riga con Testo della domanda, con tutti gli spazi iniziali:
Query Text: INSERT INTO dicquery_20200604 VALUES ($1.*) ON CONFLICT (query)
DO NOTHING;
Insert on dicquery_20200604 (cost=0.00..0.05 rows=1 width=52) (actual time=40.376..40.376 rows=0 loops=1)
Conflict Resolution: NOTHING
Conflict Arbiter Indexes: dicquery_20200604_pkey
Tuples Inserted: 1
Conflicting Tuples: 0
Buffers: shared hit=9 read=1 dirtied=1
-> Result (cost=0.00..0.05 rows=1 width=52) (actual time=0.001..0.001 rows=1 loops=1)
... e butta tutto ciò che è stato copiato direttamente nel campo per il piano, senza separare nulla:
All'uscita, otteniamo anche un bonus per il piano smontato scheda contestuale, dove la nostra richiesta si presenta in tutto il suo splendore:
JSON e YAML
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)
SELECT * FROM pg_class;
"[
{
"Plan": {
"Node Type": "Seq Scan",
"Parallel Aware": false,
"Relation Name": "pg_class",
"Alias": "pg_class",
"Startup Cost": 0.00,
"Total Cost": 1336.20,
"Plan Rows": 13804,
"Plan Width": 539,
"Actual Startup Time": 0.006,
"Actual Total Time": 1.838,
"Actual Rows": 10266,
"Actual Loops": 1,
"Shared Hit Blocks": 646,
"Shared Read Blocks": 0,
"Shared Dirtied Blocks": 0,
"Shared Written Blocks": 0,
"Local Hit Blocks": 0,
"Local Read Blocks": 0,
"Local Dirtied Blocks": 0,
"Local Written Blocks": 0,
"Temp Read Blocks": 0,
"Temp Written Blocks": 0
},
"Planning Time": 5.135,
"Triggers": [
],
"Execution Time": 2.389
}
]"
Anche con virgolette esterne, come copia pgAdmin, anche senza - inseriamo nello stesso campo, l'output è bello:
Visualizzazione avanzata
Tempo di pianificazione / Tempo di esecuzione
Ora puoi vedere meglio dove è andato il tempo extra durante l'esecuzione della query:
Temporizzazione I/O
A volte devi affrontare una situazione in cui, in termini di risorse, sembra che non sia stato letto e scritto troppo, ma sembra che il tempo di esecuzione sia incongruamente lungo per qualche motivo.
C'è da dire qui:Oh, probabilmente, in quel momento il disco sul server era troppo sovraccarico, ecco perché ci è voluto così tanto tempo per leggere!"Ma in qualche modo non è molto preciso...
Ma può essere determinato in modo assolutamente affidabile. Il fatto è che tra le opzioni di configurazione del server PG ci sono track_io_timing
Abilita le operazioni di I/O temporizzate. Questa impostazione è disabilitata per impostazione predefinita, poiché richiede al sistema operativo di interrogare costantemente l'ora corrente, il che può rallentare notevolmente le cose su alcune piattaforme. Puoi utilizzare l'utilità pg_test_timing per stimare l'overhead dei tempi sulla tua piattaforma. Le statistiche di I/O possono essere ottenute attraverso la vista pg_stat_database, nell'uscita EXPLAIN (quando viene utilizzato il parametro BUFFERS) e attraverso la vista pg_stat_statements.
Questa opzione può essere abilitata anche all'interno di una sessione locale:
SET track_io_timing = TRUE;
Bene, ora la parte migliore è che abbiamo imparato a comprendere e visualizzare questi dati, tenendo conto di tutte le trasformazioni dell'albero di esecuzione:
Qui puoi vedere che su 0.790 ms del tempo di esecuzione totale, 0.718 ms sono stati necessari per leggere una pagina di dati, 0.044 ms per scriverla e solo 0.028 ms sono stati spesi per tutte le altre attività utili!
Futuro con PostgreSQL 13
Per una panoramica completa delle novità, vedere
Buffer di pianificazione
La contabilizzazione delle risorse assegnate allo scheduler si riflette in un'altra patch che non è correlata a pg_stat_statements. EXPLAIN con l'opzione BUFFERS riporterà il numero di buffer utilizzati durante la fase di pianificazione:
Seq Scan on pg_class (actual rows=386 loops=1) Buffers: shared hit=9 read=4 Planning Time: 0.782 ms Buffers: shared hit=103 read=11 Execution Time: 0.219 ms
Ordinamento incrementale
Nei casi in cui è necessario l'ordinamento per molte chiavi (k1, k2, k3…), il pianificatore può ora trarre vantaggio dal sapere che i dati sono già ordinati per molte delle prime chiavi (ad es. k1 e k2). In questo caso non è possibile riordinare nuovamente tutti i dati, ma suddividerli in gruppi successivi con gli stessi valori di k1 e k2, e “riordinarli” tramite la chiave k3.
Pertanto, l'intero ordinamento si scompone in più ordinamenti successivi di dimensioni inferiori. Ciò riduce la quantità di memoria richiesta e consente inoltre di restituire i primi dati prima che tutto l'ordinamento sia completo.
Incremental Sort (actual rows=2949857 loops=1) Sort Key: ticket_no, passenger_id Presorted Key: ticket_no Full-sort Groups: 92184 Sort Method: quicksort Memory: avg=31kB peak=31kB -> Index Scan using tickets_pkey on tickets (actual rows=2949857 loops=1) Planning Time: 2.137 ms Execution Time: 2230.019 ms
Miglioramenti UI/UX
Gli screenshot sono ovunque!
Ora su ogni scheda c'è un'opportunità per farlo rapidamente prendi uno screenshot della scheda negli appunti per l'intera larghezza e profondità della linguetta - "vista" in alto a destra:
In realtà, la maggior parte delle immagini per questa pubblicazione sono state ottenute in questo modo.
Raccomandazioni sui nodi
Non ce ne sono solo di più, ma su ognuno che puoi
Rimozione dall'archivio
Alcuni hanno chiesto la possibilità di farlo eliminare "assolutamente" anche piani che non sono pubblicati nell'archivio - per favore, fai clic sull'icona corrispondente:
Bene, non dimentichiamo che abbiamo
Fonte: habr.com