Îmbunătățim planurile de interogare PostgreSQL și mai mult

Acum șase luni am prezentat explain.tensor.ru — un serviciu pentru analiza și vizualizarea planurilor de interogări pentru PostgreSQL.

Îmbunătățim planurile de interogare PostgreSQL și mai mult

În luna care a trecut, am făcut o prezentare pe această temă la PGConf.Russia 2020 , am pregătit un articol generaldespre accelerarea interogărilor SQL bazat pe recomandările pe care le oferă… dar cel mai important este că am strâns feedback-ul vostru și am analizat cazuri reale de utilizare. Și acum suntem pregătiți să vă povestim despre noile funcționalități de care puteți beneficia.

Suport pentru diferite formate de planuri

Plan din log, împreună cu interogarea

Direct din consolă, selectăm întregul bloc, începând cu linia ce conține

Textul interogării , inclusiv toate spațiile albe de la început:Textul interogării: INSERT INTO dicquery_20200604 VALUES ($1.*) ON CONFLICT (query) DO NOTHING; Inserare în dicquery_20200604 (cost=0.00..0.05 rânduri=1 lățime=52) (timp efectiv=40.376..40.376 rânduri=0 bucle=1) Rezolvarea conflictelor: NIMIC Indici arbiteri de conflict: dicquery_20200604_pkey Tupluri inserate: 1 Tupluri în conflict: 0 Buffere: hit partajat=9 citit=1 murdărit=1 -> Rezultatul (cost=0.00..0.05 rânduri=1 lățime=52) (timp efectiv=0.001..0.001 rânduri=1 bucle=1)

        … și aruncăm tot ce am copiat direct în câmpul pentru plan, fără a împărți nimic:

La final primim, pe lângă planul analizat, și

Îmbunătățim planurile de interogare PostgreSQL și mai mult

tabul «context» , unde interogarea noastră este prezentată în toată splendoarea sa:JSON și YAML

Îmbunătățim planurile de interogare PostgreSQL și mai mult

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
  }
]"

Indiferent dacă cu ghilimelele exterioare, așa cum copiază pgAdmin, sau fără — aruncăm în același câmp, și rezultatul este – frumusețe:

Vizualizare extinsă

Îmbunătățim planurile de interogare PostgreSQL și mai mult

Timp de planificare / Timp de execuție

Acum se vede mai bine unde s-a dus timpul suplimentar în timpul execuției interogării:

Timp I/O

Îmbunătățim planurile de interogare PostgreSQL și mai mult

Uneori trebuie să ne confruntăm cu situații în care în plan părea că nu s-au citit-scris prea multe resurse, dar timpul de execuție era disproporționat de mare.

Aici trebuie să spunem: "

Oh, probabil în acel moment discul de pe server a fost suprasolicitat, de aceea a durat atât de mult citirea!" Dar cumva nu este foarte precis…Însă acest lucru poate fi determinat absolut exact. Totul se bazează pe faptul că printre opțiunile de configurare ale serverului PG există

Но можно это определить абсолютно достоверно. Дело в том, что среди опций конфигурации PG-сервера есть track_io_timing:

Activează măsurarea timpului operațiilor de intrare/ieșire. Această opțiune este dezactivată implicit, deoarece necesită solicitarea constantă a timpului curent de la sistemul de operare, ceea ce poate încetini semnificativ funcționarea pe unele platforme. Pentru a evalua costurile măsurării timpului pe platforma ta, poți folosi utilitarul pg_test_timing. Statisticile de intrare/ieșire pot fi obținute prin vizualizarea pg_stat_database, în rezultatul EXPLAIN (când se folosește opțiunea BUFFERS) și prin vizualizarea pg_stat_statements.

Această opțiune poate fi activată și în cadrul unei sesiuni locale:

SET track_io_timing = TRUE;

Și acum, partea cea mai plăcută — am învățat să înțelegem și să afișăm aceste date ținând cont de toate transformările arborelui de execuție:

Îmbunătățim planurile de interogare PostgreSQL și mai mult

Aici se poate observa că din 0.790ms timp total de execuție, 0.718ms a fost consumat de citirea unei pagini de date, 0.044ms — scrierea acesteia, iar pentru toată celelalte activități utile au fost cheltuite doar 0.028ms!

Viitorul cu PostgreSQL 13

Pentru a consulta întreaga revizuire a noutăților poți citi articolul detaliat, iar noi ne vom concentra pe modificările din planuri.

Planning buffers

Considerarea resurselor alocate planificatorului a fost reflectată și într-un alt patch, care nu se referă la pg_stat_statements. EXPLAIN cu opțiunea BUFFERS va raporta numărul de buffere utilizate în etapa de planificare:

 Seq Scan on pg_class (atuar 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

Îmbunătățim planurile de interogare PostgreSQL și mai mult

Sortare incrementală

În cazurile în care este necesară sortarea pe mai multe chei (k1, k2, k3…), planificatorul poate folosi acum informația că datele sunt deja sortate pe câteva dintre cheile inițiale (de exemplu, k1 și k2). În acest caz, nu mai este nevoie să re-sortatezi toate datele din nou, ci se pot împărți în grupe secvențiale cu valori identice pentru k1 și k2 și „d_sorta” pe cheia k3.

Astfel, întreaga sortare se descompune în mai multe sortări secvențiale de dimensiuni mai mici. Aceasta reduce volumul de memorie necesar și permite, de asemenea, returnarea primelor date mai repede decât când toată sortarea este complet finalizată.

 Incremental Sort (atuar 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 (atuar rows=2949857 loops=1)
 Planning Time: 2.137 ms
 Execution Time: 2230.019 ms

Îmbunătățim planurile de interogare PostgreSQL și mai mult
Îmbunătățim planurile de interogare PostgreSQL și mai mult

Îmbunătățiri UI/UX

Capturi de ecran, sunt peste tot!

Acum, pe fiecare tab, a apărut posibilitatea de a copia rapid un screenshot al tab-ului în clipboard pe întreaga lățime și adâncime a tab-ului — „ținta” în dreapta sus:

Îmbunătățim planurile de interogare PostgreSQL și mai mult

De fapt, majoritatea imaginilor pentru această publicație au fost obținute exact așa.

Recomandări la noduri

Nu doar că a devenit mai multe, dar pentru fiecare se poate citi detaliat în articol, accesând linkul:

Îmbunătățim planurile de interogare PostgreSQL și mai mult

Ștergerea din arhivă

Unii au cerut foarte mult să adăugăm posibilitatea de a elimina „complet” chiar și planurile nepublicate din arhivă — vă rugăm, este suficient să apăsați pictograma corespunzătoare:

Îmbunătățim planurile de interogare PostgreSQL și mai mult

Ei bine, și nu uităm că avem un grup de suport, unde puteți scrie observațiile și sugestiile dumneavoastră.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster