Pół roku temu
W ciągu ostatnich miesięcy zrobiliśmy o nim
A teraz jesteśmy gotowi, aby opowiedzieć Ci o nowych funkcjach, z których możesz korzystać.
Obsługa różnych formatów planów
Plan z dziennika wraz z wnioskiem
Bezpośrednio z konsoli wybieramy cały blok, zaczynając od linii z Tekst zapytania, ze wszystkimi wiodącymi spacjami:
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)
... i wrzuć wszystko skopiowane bezpośrednio w pole do planu, nie oddzielając niczego:
Na wyjściu otrzymujemy również premię do zdemontowanego planu zakładka kontekstu, gdzie nasza prośba jest przedstawiona w całej okazałości:
JSON i 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
}
]"
Nawet z cudzysłowami zewnętrznymi, jak kopiuje pgAdmin, nawet bez - wrzucamy w to samo pole, wyjście jest piękne:
Zaawansowana wizualizacja
Czas planowania / Czas realizacji
Teraz możesz lepiej zobaczyć, gdzie poszedł dodatkowy czas podczas wykonywania zapytania:
Taktowanie we/wy
Czasami masz do czynienia z sytuacją, w której pod względem zasobów wydaje się, że nie przeczytano i nie napisano zbyt wiele, ale wydaje się, że czas wykonania jest z jakiegoś powodu niewspółmiernie długi.
Tu trzeba powiedzieć:Och, prawdopodobnie w tym momencie dysk na serwerze był zbyt przeciążony, dlatego tak długo trwało czytanie!„Ale jakoś nie jest to bardzo dokładne ...
Ale można to ustalić absolutnie niezawodnie. Faktem jest, że wśród opcji konfiguracyjnych serwera PG są track_io_timing
Umożliwia czasowe operacje wejścia/wyjścia. To ustawienie jest domyślnie wyłączone, ponieważ wymaga od systemu operacyjnego ciągłego sprawdzania aktualnego czasu, co może znacznie spowolnić działanie na niektórych platformach. Możesz użyć narzędzia pg_test_timing, aby oszacować obciążenie czasowe na swojej platformie. Statystyki I/O można uzyskać poprzez widok pg_stat_database, w wyjściu EXPLAIN (w przypadku użycia parametru BUFERY) i przez widok pg_stat_statements.
Tę opcję można również włączyć w ramach sesji lokalnej:
SET track_io_timing = TRUE;
Cóż, teraz najlepsze jest to, że nauczyliśmy się rozumieć i wyświetlać te dane, biorąc pod uwagę wszystkie przekształcenia drzewa wykonania:
Tutaj widać, że z 0.790 ms całkowitego czasu wykonania, 0.718 ms zajęło odczytanie jednej strony danych, 0.044 ms - jej zapisanie, a tylko 0.028 ms zostało wydane na wszystkie inne przydatne czynności!
Przyszłość z PostgreSQL 13
Aby uzyskać pełny przegląd nowości, zobacz
Bufory planowania
Uwzględnianie zasobów przydzielonych do programu planującego jest odzwierciedlone w innej poprawce, która nie jest związana z pg_stat_statements. EXPLAIN z opcją BUFFERS poda liczbę buforów użytych w fazie planowania:
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
Sortowanie przyrostowe
W przypadkach, gdy potrzebne jest sortowanie według wielu kluczy (k1, k2, k3…), planista może teraz skorzystać z wiedzy, że dane są już posortowane według kilku pierwszych kluczy (np. k1 i k2). W takim przypadku nie można przesortować wszystkich danych od nowa, tylko podzielić je na kolejne grupy o jednakowych wartościach k1 i k2 i „przesortować” je według klucza k3.
W ten sposób całe sortowanie rozpada się na kilka kolejnych sortowań o mniejszym rozmiarze. Zmniejsza to wymaganą ilość pamięci, a także umożliwia zwrócenie pierwszych danych przed zakończeniem całego sortowania.
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
Ulepszenia interfejsu użytkownika/UX
Zrzuty ekranu są wszędzie!
Teraz na każdej karcie istnieje możliwość szybkiego zrób zrzut ekranu karty do schowka na całą szerokość i głębokość zakładki - „wzrok” prawy górny:
Właściwie większość zdjęć do tej publikacji została uzyskana w ten sposób.
Zalecenia dotyczące węzłów
Nie tylko jest ich więcej, ale o każdym można
Usuwanie z archiwum
Niektórzy prosili o możliwość usuń „absolutnie” nawet plany, które nie są publikowane w archiwum - wystarczy kliknąć odpowiednią ikonę:
Cóż, nie zapominajmy, że mamy
Źródło: www.habr.com