Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Kalahating taon na ang nakalipas nagpresenta kami explain.tensor.ru - pampubliko serbisyo para sa pag-parse at pag-visualize ng mga query plan sa PostgreSQL.

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Sa nakalipas na mga buwan ay ginawa namin ang tungkol sa kanya ulat sa PGConf.Russia 2020, naghanda ng buod artikulo sa pagpapabilis ng mga query sa SQL batay sa mga rekomendasyong ibinibigay nito... ngunit ang pinakamahalaga, kinolekta namin ang iyong feedback at tiningnan ang mga totoong sitwasyon ng paggamit.

At ngayon handa na kaming pag-usapan ang mga bagong pagkakataon na magagamit mo.

Suporta para sa iba't ibang mga format ng plano

Magplano mula sa log, kasama ang kahilingan

Direkta mula sa console, piliin ang buong bloke, simula sa linya na may Teksto ng Query, kasama ang lahat ng nangungunang puwang:

        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)

... at ilagay ang lahat ng kinopya nang direkta sa field ng plano, nang hindi naghihiwalay ng anuman:

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Sa dulo makakakuha tayo ng bonus sa na-disassemble na plano at tab na "konteksto"., kung saan ang aming kahilingan ay ipinakita sa buong kaluwalhatian nito:

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

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

Alinman sa mga panlabas na quote, bilang mga kopya ng pgAdmin, o wala - itinapon namin ito sa parehong larangan, at ang output ay kagandahan:

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Advanced na Visualization

Oras ng Pagpaplano/Oras ng Pagpapatupad

Mas makikita mo na ngayon kung saan ginugol ang dagdag na oras sa pagsasagawa ng query:

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

I/O Timing

Minsan kailangan mong harapin ang isang sitwasyon kung saan, sa mga tuntunin ng mga mapagkukunan, tila hindi masyadong marami ang nabasa at naisulat, ngunit ang oras ng pagpapatupad ay tila hindi angkop na mahaba.

Narito kailangan nating sabihin: "Oh, marahil sa sandaling iyon ang disk sa server ay sobrang na-overload, kaya naman natagalan ang pagbabasa!"Ngunit sa paanuman ito ay hindi masyadong tumpak...

Ngunit ito ay maaaring matukoy na ganap na mapagkakatiwalaan. Ang katotohanan ay kabilang sa mga pagpipilian sa pagsasaayos ng PG server ay mayroon track_io_timing:

Pinapagana ang timing ng mga operasyon ng I/O. Ang pagpipiliang ito ay hindi pinagana bilang default dahil nangangailangan ito ng patuloy na pagtatanong sa operating system para sa kasalukuyang oras, na maaaring makabuluhang makapagpabagal sa pagganap sa ilang mga platform. Upang tantyahin ang halaga ng timing sa iyong platform, maaari mong gamitin ang pg_test_timing utility. Maaaring makuha ang mga istatistika ng I/O sa pamamagitan ng pg_stat_database view, sa EXPLAIN output (kapag ginamit ang BUFFERS parameter) at sa pamamagitan ng pg_stat_statements view.

Ang pagpipiliang ito ay maaari ding paganahin sa loob ng isang lokal na sesyon:

SET track_io_timing = TRUE;

Well, ngayon ang pinakamagandang bahagi ay natutunan naming maunawaan at ipakita ang data na ito na isinasaalang-alang ang lahat ng mga pagbabagong-anyo ng puno ng pagpapatupad:

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Dito makikita mo na sa 0.790ms ng kabuuang oras ng pagpapatupad, 0.718ms ang nagbasa ng isang pahina ng data, 0.044ms ang sumulat nito, at 0.028ms lang ang ginugol sa lahat ng iba pang kapaki-pakinabang na aktibidad!

Ang hinaharap sa PostgreSQL 13

Makakahanap ka ng buong pangkalahatang-ideya ng mga inobasyon sa isang detalyadong artikulo, at partikular na pinag-uusapan natin ang tungkol sa mga pagbabago sa mga plano.

Mga buffer sa pagpaplano

Ang accounting para sa mga mapagkukunang inilalaan sa scheduler ay makikita sa isa pang patch na hindi nauugnay sa pg_stat_statements. Ipaliwanag gamit ang opsyong BUFFERS ay mag-uulat ng bilang ng mga buffer na ginamit sa yugto ng pagpaplano:

 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

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Incremental na pag-uuri

Sa mga kaso kung saan kailangan ang pag-uuri sa maraming key (k1, k2, k3...), maaari na ngayong samantalahin ng planner ang kaalaman na ang data ay pinagsunod-sunod na sa ilan sa mga unang key (halimbawa, k1 at k2). Sa kasong ito, hindi mo maaaring muling pag-uri-uriin ang lahat ng data, ngunit hatiin ito sa sunud-sunod na mga grupo na may parehong mga halaga ng k1 at k2, at "muling pag-uri-uriin" ito sa pamamagitan ng key k3.

Kaya, ang buong pag-uuri ay nahahati sa ilang magkakasunod na uri ng mas maliit na sukat. Binabawasan nito ang dami ng memorya na kinakailangan at pinapayagan din ang unang data na ma-output bago makumpleto ang buong pag-uuri.

 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

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa
Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Mga pagpapahusay sa UI/UX

Mga screenshot, nasa lahat sila!

Ngayon sa bawat tab mayroong isang pagkakataon upang mabilis kumuha ng screenshot ng tab sa clipboard ang buong lapad at lalim ng tab - "paningin" sa kanang itaas:

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Sa katunayan, karamihan sa mga larawan para sa publikasyong ito ay nakuha sa ganitong paraan.

Mga rekomendasyon sa mga node

Hindi lamang nagkaroon ng higit pa sa kanila, ngunit maaari mo ring pag-usapan ang bawat isa basahin ang artikulo nang detalyadosa pamamagitan ng pagsunod sa link:

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Tinatanggal mula sa archive

Ang ilang mga tao ay talagang humiling na idagdag ang opsyon tanggalin ang "ganap" kahit na ang mga plano na hindi nai-publish sa archive - mangyaring i-click lamang ang naaangkop na icon:

Ang pag-unawa sa mga plano ng query sa PostgreSQL ay mas maginhawa

Well, huwag kalimutan na mayroon tayo Grupo ng Suporta, kung saan maaari mong isulat ang iyong mga komento at mungkahi.

Pinagmulan: www.habr.com

Magdagdag ng komento