Половин година назад — публичен към PostgreSQL.

През изминалите месеци направихме за него , подготвихме обобщаваща въз основа на препоръките, които той предоставя… но най-важното — събрахме вашите отзиви и следяхме реални примери за ползване.
И сега сме готови да разкажем за новите възможности, с които можете да се възползвате.
Поддръжка на различни формати на планове
План от лог, заедно със заявката
Просто от конзолата избираме целия блок, започвайки от реда с Query Text, с всички водещи интервали:
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-сървъра има :
Включва измерване на времето на входно/изходни операции. Този параметър по подразбиране е деактивиран, тъй като за него е необходимо постоянно да се запитва текущото време от операционната система, което може значително да забави работата на някои платформи. За оценка на разходите за измерване на времето на вашата платформа можете да използвате утилитата pg_test_timing. Статистиката на входно/изходните операции може да бъде получена чрез представянето pg_stat_database, в изхода на EXPLAIN (когато се използва параметърът BUFFERS) и чрез представянето pg_stat_statements.
Този параметър може да бъде включен и в рамките на локална сесия:
SET track_io_timing = TRUE;Но сега най-хубавото — научихме се да разбираме и показваме тези данни с всичките трансформации на изпълнителното дърво:

Тук можем да забележим, че от 0.790ms общо време на изпълнение 0.718ms е отнело четенето на една страница данни, 0.044ms — записването й, а за цялата останала полезна дейност е било използвано само 0.028ms!
Бъдещето с PostgreSQL 13
Можете да се запознаете с пълния обзор на нововъведенията , а ние конкретно за промените в плановете.
Планиране на буфери
Отчетът за ресурсите, предоставени на планировщика, е отразен и в още един пач, несвързан с pg_stat_statements. EXPLAIN с опция 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.
Скриншоти, те са навсякъде!
Сега на всяка вкладка се появи възможност бързо да направите скрийншот на раздела в буферната памет по цялата ширина и дълбочина на раздела — «прицел» вдясно-нагоре:

Всъщност, повечето изображения за тази публикация са получени точно така.
Препоръки на възлите
Не само, че стана повече, но и за всеки един може , като последвате линка:

Изтриване от архива
Някои много поискаха да бъде добавена възможността да се изтриват «напълно» дори непубликуваните в архива планове — моля, просто натиснете съответната икона:

И не забравяйте, че имаме , където можете да пишете вашите забележки и предложения.
Източник: habr.com
