Пред половина година
Во текот на изминатите месеци зборувавме за него
И сега сме подготвени да разговараме за нови можности што можете да ги искористите.
Поддршка за различни формати на планови
Планирајте од дневникот, заедно со барањето
Директно од конзолата, изберете го целиот блок, почнувајќи од линијата со Текст за барање, со сите водечки простори:
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)
... и ставете сè што е ископирано директно во полето за план, без да одвојувате ништо:
На крајот добиваме бонус на расклопениот план и табот „контекст“., каде што нашето барање е претставено во сиот негов сјај:
JSON и 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
}
]"
Или со надворешни наводници, како pgAdmin копии, или без - го фрламе во истото поле, а излезот е убавина:
Напредна визуелизација
Време на планирање/Време на извршување
Сега можете подобро да видите каде е потрошено дополнителното време за извршување на барањето:
I/O Тајминг
Понекогаш треба да се справите со ситуација кога, во однос на ресурсите, се чини дека не е премногу прочитано и напишано, но времето на извршување се чини дека е несоодветно долго.
Тука мораме да кажеме:“О, веројатно во тој момент дискот на серверот беше премногу преоптоварен, затоа и требаше толку долго да се прочита!„Но, некако ова не е многу точно ...
Но, ова може да се утврди апсолутно веродостојно. Факт е дека меѓу опциите за конфигурација на PG серверот постои track_io_timing
Овозможува тајминг на I/O операции. Оваа опција е стандардно оневозможена бидејќи бара постојано барање на оперативниот систем за моменталното време, што може значително да ги забави перформансите на некои платформи. За да ги процените трошоците за тајмингот на вашата платформа, можете да ја користите алатката pg_test_timing. Статистиката за влез/излез може да се добие преку приказот pg_stat_database, во излезот EXPLAIN (кога се користи параметарот BUFFERS) и преку приказот pg_stat_statements.
Оваа опција може да се овозможи и во рамките на локална сесија:
SET track_io_timing = TRUE;
Па, сега најдобриот дел е што научивме да ги разбираме и прикажуваме овие податоци земајќи ги предвид сите трансформации на дрвото за извршување:
Овде можете да видите дека од 0.790 ms од вкупното време на извршување, 0.718 ms биле потребни за читање на една страница со податоци, 0.044 ms за пишување, а само 0.028 ms биле потрошени за сите други корисни активности!
Иднината со PostgreSQL 13
Можете да најдете целосен преглед на иновациите
Бафери за планирање
Сметководството за ресурсите доделени на распоредувачот се рефлектира во друга закрпа која не е поврзана со pg_stat_statements. Објаснете со опцијата BUFFERS ќе го пријави бројот на бафери користени во фазата на планирање:
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
Инкрементално сортирање
Во случаи кога е потребно сортирање на многу клучеви (k1, k2, k3...), планерот сега може да го искористи знаењето дека податоците се веќе подредени на неколку од првите копчиња (на пример, k1 и k2). Во овој случај, не можете повторно да ги подредите сите податоци, туку да ги поделите во последователни групи со исти вредности на k1 и k2 и да ги „подредите“ по клучот k3.
Така, целото сортирање е поделено на неколку последователни видови со помали димензии. Ова го намалува количеството потребна меморија и исто така овозможува да се излезат првите податоци пред да се заврши целото сортирање.
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
Подобрувања на UI/UX
Слики од екранот, тие се насекаде!
Сега на секое јазиче има можност за брзо направете слика од екранот на јазичето до таблата со исечоци целата ширина и длабочина на јазичето - „поглед“ на десниот врв:
Всушност, повеќето од сликите за оваа публикација се добиени на овој начин.
Препораки за јазли
Не само што има повеќе од нив, туку можете да зборувате и за секоја од нив
Бришење од архивата
Некои луѓе навистина побараа да ја додадат опцијата избришете „целосно“ дури и планови кои не се објавени во архивата - само кликнете на соодветната икона:
Па, не заборавајте дека имаме
Извор: www.habr.com