Comprensione dei piani di query PostgreSQL ancora più conveniente

Sei mesi fa abbiamo presentato spiegare.tensore.ru - pubblico servizio per l'analisi e la visualizzazione dei piani di query a PostgreSQL.

Comprensione dei piani di query PostgreSQL ancora più conveniente

Negli ultimi mesi abbiamo fatto di lui relazione al PGConf.Russia 2020, ha preparato un riassunto articolo sull'accelerazione delle query SQL sulla base delle raccomandazioni fornite... ma soprattutto, abbiamo raccolto il tuo feedback e esaminato casi d'uso reali.

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:

Comprensione dei piani di query PostgreSQL ancora più conveniente

All'uscita, otteniamo anche un bonus per il piano smontato scheda contestuale, dove la nostra richiesta si presenta in tutto il suo splendore:

Comprensione dei piani di query PostgreSQL ancora più conveniente

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:

Comprensione dei piani di query PostgreSQL ancora più conveniente

Visualizzazione avanzata

Tempo di pianificazione / Tempo di esecuzione

Ora puoi vedere meglio dove è andato il tempo extra durante l'esecuzione della query:

Comprensione dei piani di query PostgreSQL ancora più conveniente

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:

Comprensione dei piani di query PostgreSQL ancora più conveniente

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 in un articolo dettagliato, e stiamo parlando specificamente di cambiamenti nei piani.

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

Comprensione dei piani di query PostgreSQL ancora più conveniente

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

Comprensione dei piani di query PostgreSQL ancora più conveniente
Comprensione dei piani di query PostgreSQL ancora più conveniente

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:

Comprensione dei piani di query PostgreSQL ancora più conveniente

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 leggi l'articolo nel dettaglioseguendo il link:

Comprensione dei piani di query PostgreSQL ancora più conveniente

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:

Comprensione dei piani di query PostgreSQL ancora più conveniente

Bene, non dimentichiamo che abbiamo Gruppo di supportodove puoi scrivere i tuoi commenti e suggerimenti.

Fonte: habr.com

Aggiungi un commento