Есебіңіз дерекқор хостында шамамен бір секундта және VPN арқылы төрт секундта аяқталады, ал psql басып шығаратын сан тікелей дерекқорды нұсқайды. Бұл сан клиент жағындағы секундомер, сервер өлшемі емес. Ол өтініштің сыртқа шығу жолын, жауап күтуді және қайта оралған жолдарды қамтиды. Осы үшеуін ажырату ғана қай жақты реттеу керектігін білудің жалғыз жолы.

psql таймері шын мәнінде нені өлшейді

\timing on клиент өтінішті сокетке жазбай тұрып секундомерді іске қосады және сол нәтиженің соңғы жолы оқылғанда тоқтатады. Сервердің өз орындалуы сол терезенің әлдебір жерінде, сондай-ақ пакеттердің туннельде өткізетін әрбір миллисекунды да. Шығыста ешнәрсе оларды ажыратпайды. EXPLAIN да сан басып шығарады, бірақ оны сервер жасайды және клиенттің күтуін есепке алмайды. Екі сан, екі түрлі сұрақ.

Бір сессияны бастаңыз, уақыт өлшеуді қосулы қалдырыңыз және керек өтінішті соның ішінен орындаңыз. Сессияны қайта пайдалану қосылу құнын бірінші өлшемнен тыс қалдырады.

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';"

Сан әлі де нәтижені жіберуді қамтиды, бұл осында керек нәрсе. Ол жаңа шақыру қосатын қосылу мен аутентификация алмасуын енді қамтымайды.

Бір өтінішті үш жолмен салыстырыңыз

Сол өтінішті Unix сокеті, LAN мекенжайы және VPN хост атауы арқылы орындап, үшеуін салыстырыңыз. Тек соңғысы баяу болса, сұрау айнымалы емес.

Әр шақыру алдымен қосылады, содан кейін ғана өтінішті өлшейді, сондықтан қосылу құны саннан тыс қалады, ал жіберу оның ішінде қалады. WHERE тармағын, жол санын және клиент машинасын бірдей ұстаңыз, әйтпесе жолдарды емес, жұмыс жүктемелерін салыстырасыз.

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;"

LAN-да айырмашылық әдетте елемеуге болатындай аз; VPN арқылы жиі олай емес. Үш нәтижені реттеу кейін қай күтуге шабуыл жасау керектігін айтады.

Баяу жергілікті сокет сервер жұмысын немесе жоспарлауды білдіреді. Баяу LAN нәтижесі сұрауды немесе оның жылжытатын көлемін білдіреді. Тек VPN нәтижесінің баяу болуы жолдағы кідіріс, MTU немесе қолжетімді өткізу қабілетін білдіреді, және ешбір индексті өзгерту оны түзетпейді.

Сервердің өз орындалу уақытын алыңыз

Сервер қанша уақыт жұмсағанын хабарлай алады, клиенттің санымен салыстырылатын сан — дәл сол. EXPLAIN ANALYZE-пен өтінішті орындайды және жоспардың ішінде жоспарлау мен орындалу уақытын басып шығарады, ал BUFFERS жылы жүгірісті суық жүгіріске қарсы жиі түсіндіретін кэш мінезін қосады. Жазуды ниет етпесеңіз, оны жазу өтініштеріне бағыттамаңыз. Тек оқуға арналған көшірмеде бұл бастаудың ең қауіпсіз орны, және psql анықтамасы таймердің клиент жағындағы ауқымын құжаттайды.

Қосымша бұрыннан орындайтын өтініштер үшін pg_stat_statements ештеңені қайта іске қоспай-ақ сервер жағындағы орындалуды жинақтайды. Жолдар қалыпқа келтірілген сұрау бойынша, сондықтан бір жазба бірнеше шақыру орнын қамтуы мүмкін.

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

Баған атаулары шығарылымға қарай әртүрлі: PostgreSQL 13 және одан кейінгілер mean_exec_time көрсетеді, ал ескі нұсқалар оны mean_time деп атайды, сондықтан мынамен тексеріңіз: \d pg_stat_statements, егер бұл сұрау қате берсе. Бұл мәндер жоспарлауды және сіздің клиентіңізге дейінгі сапарды қамтымайды. Дәл осы шығарып тастау оларды салыстыру үшін пайдалы етеді.

Барып-қайтуларды санаңыз, тек миллисекундтарды емес

Екі жүз шағын тәуелді өтініштен құралған есеп жол қосатын кез келген кідірісті екі жүзге көбейтеді. Миллион жол қайтаратын бір өтініш сол кідірісті бір рет төлейді, содан кейін ұзақ уақыт өткізу қабілетін төлейді. Екеуі де клиент таймерінде бірдей көрінеді және оларға қарама-қарсы түзетулер қажет.

Өтініш санын болжамай, өлшеңіз. Жалпыны оқыңыз, есепті бір рет орындаңыз, содан кейін қайта оқып, азайтыңыз.

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

Егер дельта үлкен болса және әр өтініш серверде арзан болса, топтастыру — төленетін түзету. Тәуелді сұрауларды біріктіріңіз, бір жиынға негізделген өтініш қолданыңыз немесе циклді курсордан басқарыңыз. Интерактивті psql ішінде, \set FETCH_COUNT 1000 үлкен нәтижені топтамалармен келуге мәжбүр етеді және жіберу мен клиент жадысының мінезін өзгертеді. Ол сервер жұмысын азайтпайды, сондықтан баяу сұрауды құтқармайды.

Туннельді қайта жіберулер мен MTU тоқырауларына тексеріңіз

Кішкентай өтініштер жылдам, ал үлкен нәтижелер жарты жолда тоқтап қалса, сұрау әдетте дұрыс, ал жол дұрыс емес. MTU-сы негізгі буыннан төмен туннель бұғатталған ICMP-мен бірге дәл осы үлгіні жасайды: алғашқы пакеттер келеді, үлкендері жоғалады, және жіберу қайта әрекет етпейінше ілініп тұрады. Клиент жағындағы қайта жіберу санауыштары мұны көрсетеді.

Әдейі баяу жіберу жүріп жатқанда сокет пен ядро санауыштарын бақылаңыз. Қайта жіберу сомалары жинақталады, сондықтан бір үлгіні оқымай, оларды алдын ала және кейін жазып алыңыз.

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

Жіберу кезінде өсетін қайта жіберулер, 1400 байтта сәтті болып 1472-де сәтсіз болатын ping-мен бірге, дерекқор емес, MTU мәселесін нұсқайды. Туннель интерфейсінің MTU-ын төмендету немесе шлюзде MSS-ті қысу — әдеттегі түзету, және сол үш пәрмен мұны кейін растайды. Егер жіберу әлі баяу болып тұрғанда қайта жіберулер тегіс қалса, жоғалтуға емес, туннельге рұқсат етілген өткізу қабілетіне қараңыз.

Қысқа реттілік келесі баяу есепті қамтиды: бір өтінішті жергілікті, LAN-да және VPN арқылы салыстырыңыз; сервер орындалуын EXPLAIN немесе pg_stat_statements-тен оқыңыз; бір рет іске қосудың алдында және кейін шақыруларды санаңыз; және үлкен нәтиже қозғалғанда қайта жіберулерді бақылаңыз. Әр қадам жолдың бір жағын жоққа шығарады. Олардың ешқайсысы қай компонентті қайта іске қосу керектігін болжауды талап етпейді.

Қатысты мақалалар