Raporti juaj përfundon në rreth një sekondë në hostin e bazës së të dhënave dhe në katër përmes VPN, dhe numri që printon psql tregon drejt bazës së të dhënave. Ai numër është një kronometër në anën e klientit, jo një matje e serverit. Ai mbulon deklaratën në rrugën dalëse, pritjen për një përgjigje dhe rreshtat në rrugën e kthimit. Ndarja e këtyre treve është e vetmja mënyrë për të ditur cilën anë të rregulloni.

Çfarë mat vërtet kohëmatësi i psql

\timing on nis një kronometër pak përpara se klienti të shkruajë deklaratën në socket dhe e ndal kur lexohet rreshti i fundit i atij rezultati. Ekzekutimi i vetë serverit ndodhet diku brenda atij dritareje, dhe po ashtu çdo milisekondë që paketat kalojnë në tunel. Asgjë në dalje nuk i ndan ato. EXPLAIN gjithashtu printon një numër, por atë e prodhon serveri dhe përjashton pritjen e klientit. Dy numra, dy pyetje të ndryshme.

Nisni një sesion, lini matjen e kohës të aktivizuar dhe ekzekutoni deklaratën që ju intereson nga brenda tij. Ripërdorimi i një sesioni mban koston e lidhjes jashtë matjes së parë.

psql "host=db.internal port=5432 dbname=appdb user=app" \
  -c "\timing on" \
  -c "select count(*) from orders where created_at > now() - interval '1 day';"

Numri ende përfshin transferimin e rezultatit, që është ajo që dëshironi këtu. Ai nuk përfshin më shkëmbimin e lidhjes dhe vërtetimit që do të shtonte një thirrje e re.

Krahasoni një deklaratë në tre rrugë

Ekzekutoni të njëjtën deklaratë përmes socket-it Unix, adresës LAN dhe emrit të hostit VPN, dhe krahasoni të tre. Nëse vetëm i fundit është i ngadaltë, pyetja nuk është variabli.

Çdo thirrje lidhet së pari dhe vetëm pastaj mat deklaratën, kështu që kostoja e lidhjes mbetet jashtë numrit ndërsa transferimi mbetet brenda. Mbani të njëjtat klauzolën WHERE, numrin e rreshtave dhe makinën e klientit, përndryshe po krahasoni ngarkesa pune dhe jo rrugë.

psql -h /var/run/postgresql -U app -d appdb -c "\timing on" -c "select count(*) from orders;"
psql -h 10.40.0.12 -U app -d appdb -c "\timing on" -c "select count(*) from orders;"
psql -h db.vpn.internal -U app -d appdb -c "\timing on" -c "select count(*) from orders;"

Në një LAN diferenca zakonisht është mjaft e vogël për t'u injoruar; përmes VPN shpesh nuk është. Renditja e tre rezultateve ju tregon pastaj se cilën pritje të sulmoni.

Një socket lokal i ngadaltë do të thotë punë e serverit ose planifikim. Një rezultat LAN i ngadaltë do të thotë pyetja ose vëllimi që ajo lëviz. Vetëm një rezultat VPN i ngadaltë do të thotë vonesë, MTU ose gjerësi bande e disponueshme në rrugë, dhe asnjë ndryshim indeksi nuk e rregullon atë.

Nxirrni kohën e ekzekutimit të vetë serverit

Serveri mund të raportojë sa kohë ka kaluar, dhe pikërisht ai numër duhet krahasuar me atë të klientit. EXPLAIN me ANALYZE ekzekuton deklaratën dhe printon kohën e planifikimit dhe ekzekutimit brenda planit, ndërsa BUFFERS shton sjelljen e cache-it që shpesh shpjegon një ekzekutim të ngrohtë ndaj një të ftohtë. Mos e drejtoni atë në deklarata shkrimi nëse nuk synoni të shkruani. Në një replikë vetëm-lexim është vendi më i sigurt për të filluar, dhe referenca e psql dokumenton shtrirjen e kohëmatësit në anën e klientit.

Për deklaratat që aplikacioni tashmë ekzekuton, pg_stat_statements grumbullon ekzekutimin në anën e serverit pa riekzekutuar asgjë. Rreshtat janë për pyetje të normalizuar, kështu që një hyrje mund të mbulojë disa vende thirrjesh.

select calls, round(mean_exec_time::numeric, 2) as mean_ms, rows
from pg_stat_statements
order by mean_exec_time desc
limit 5;

Emrat e kolonave ndryshojnë sipas versionit: PostgreSQL 13 dhe më i ri ekspozon mean_exec_time, ndërsa versionet e vjetra e quajnë mean_time, prandaj kontrolloni me \d pg_stat_statements nëse ajo pyetje jep gabim. Këto vlera përjashtojnë planifikimin dhe përjashtojnë udhëtimin deri te klienti juaj. Pikërisht ky përjashtim i bën ato të dobishme për krahasimin.

Numëroni udhëtimet vajtje-ardhje, jo vetëm milisekondat

Një raport i ndërtuar nga dyqind deklarata të vogla të varura shumëzon me dyqind çdo vonesë që shton rruga. Një deklaratë e vetme që kthen një milion rreshta paguan atë vonesë një herë dhe pastaj paguan gjerësi bande për një kohë të gjatë. Të dyja duken njësoj në një kohëmatës klienti dhe kërkojnë rregullime të kundërta.

Matni numrin e deklaratave në vend që ta vlerësoni. Lexoni totalin, ekzekutoni raportin një herë, pastaj lexojeni përsëri dhe zbritni.

select sum(calls) as calls from pg_stat_statements;
-- run the report here
select sum(calls) as calls from pg_stat_statements;

Nëse delta është e madhe dhe çdo deklaratë është e lirë në server, grupimi është rregullimi që ia vlen. Kombinoni pyetje të varura, përdorni një deklaratë të vetme të bazuar në bashkësi ose drejtoni ciklin nga një kursor. Në psql interaktiv, \set FETCH_COUNT 1000 një rezultat i madh vjen në tufa dhe ndryshon sjelljen e transferimit dhe të memories së klientit. Ai nuk e zvogëlon punën e serverit, prandaj nuk do të shpëtojë një pyetje të ngadaltë.

Kontrolloni tunelin për ritransmetime dhe ngecje MTU

Kur deklaratat e vogla janë të shpejta dhe rezultatet e mëdha ngecin në gjysmë të rrugës, pyetja zakonisht është në rregull dhe rruga jo. Një tunel, MTU-ja e të cilit është më e ulët se lidhja bazë, së bashku me ICMP të bllokuar, prodhon pikërisht atë model: paketat e para mbërrijnë, ato të mëdha zhduken dhe transferimi varet derisa të provojë përsëri. Numëruesit e ritransmetimit në anën e klientit e tregojnë këtë.

Vëzhgoni socket-in dhe numëruesit e kernelit ndërsa kryhet një transferim qëllimisht i ngadaltë. Shumat e ritransmetimit janë kumulative, prandaj shënoni ato para dhe pas në vend që të lexoni një mostër të vetme.

ss -tin dst 10.40.0.12
netstat -s | grep -iE "retransmit|segments retransmitted"
ping -M do -s 1400 -c 3 10.40.0.12

Ritransmetimet që rriten gjatë transferimit, së bashku me një ping që ka sukses në 1400 bajt por dështon në 1472, tregojnë një problem MTU dhe jo një problem baze të dhënash. Ulja e MTU-së së ndërfaqes së tunelit ose shtrëngimi i MSS në portë është rregullimi i zakonshëm, dhe të njëjtat tre komanda e konfirmojnë më pas. Nëse ritransmetimet mbeten të sheshta ndërsa transferimi është ende i ngadaltë, shikoni gjerësinë e bandës që i lejohet tunelit dhe jo humbjet.

Një sekuencë e shkurtër mbulon raportin e radhës të ngadaltë: krahasoni një deklaratë lokalisht, në LAN dhe përmes VPN; lexoni ekzekutimin e serverit nga EXPLAIN ose pg_stat_statements; numëroni thirrjet para dhe pas një ekzekutimi; dhe vëzhgoni ritransmetimet ndërsa rezultati i madh lëviz. Çdo hap përjashton një anë të rrugës. Asnjë prej tyre nuk kërkon të hamendësoni cilin komponent të rinisni.

Artikuj të ngjashëm