Ulepszanie dla leniwych: jak PostgreSQL 12 zwiększa wydajność

Ulepszanie dla leniwych: jak PostgreSQL 12 zwiększa wydajność

PostgreSQL 12, ostatnia wersja „najlepszej na świecie relacyjnej bazy danych z otwartym kodem źródłowym”, ukaże się za kilka tygodni (jeśli wszystko pójdzie zgodnie z planem). To odpowiada zwyczajowemu harmonogramowi — nowa wersja z mnóstwem nowych możliwości pojawia się co roku, i, szczerze mówiąc, to jest imponujące. Dlatego stałem się aktywnym członkiem społeczności PostgreSQL.

Moim zdaniem, w przeciwieństwie do poprzednich wydań, PostgreSQL 12 nie zawiera jednej lub dwóch rewolucyjnych funkcji (jak na przykład partycjonowanie czy równoległość zapytań). Żartobliwie wspomniałem, że główną atrakcją PostgreSQL 12 jest większa stabilność. A czy nie tego potrzebujesz, gdy zarządzasz krytycznie ważnymi danymi swojego biznesu?

Jednak PostgreSQL 12 na tym się nie kończy: dzięki nowym możliwościom i udoskonaleniom aplikacje będą działać lepiej, a od Ciebie wymaga się tylko przeprowadzenia aktualizacji!

(Cóż, może jeszcze przebudować indeksy, ale w tej wersji to nie jest tak straszne, jak jesteśmy przyzwyczajeni.)

Będzie świetnie — zaktualizować PostgreSQL i od razu cieszyć się znacznymi ulepszeniami bez zbędnych działań. Kilka lat temu analizowałem aktualizację z PostgreSQL 9.4 do PostgreSQL 10 i zobaczyłem, jak przyspieszyła aplikacja dzięki ulepszonym możliwościom równoległości zapytań w PostgreSQL 10. I co najważniejsze, ode mnie prawie nic nie było wymagane (tylko ustawić parametr konfiguracyjny max_parallel_workers).

Zgódź się, wygodnie jest, kiedy od razu po aktualizacji aplikacje działają lepiej. A my naprawdę staramy się zadowolić użytkowników, bo PostgreSQL ma ich coraz więcej.

A jak prosta aktualizacja do PostgreSQL 12 sprawi, że będziesz szczęśliwy? Już opowiadam.

Serio, znaczące ulepszenia w indeksowaniu

Bez indeksowania baza danych daleko nie zajdzie. Jak szybko znaleźć informacje? Fundamentalny system indeksowania PostgreSQL nazywa się B-drzewo. Ten typ indeksu jest zoptymalizowany dla systemów przechowywania.

Po prostu używamy operatora CREATE INDEX ON some_table (some_column), a PostgreSQL wykonuje dużą część pracy, aby utrzymać aktualność indeksu, podczas gdy my cały czas wstawiamy, aktualizujemy i usuwamy wartości. Wszystko działa samo, jakby to było magiczne.

Ale indeksy PostgreSQL mają jeden problem — one puchną i zajmują dodatkowe miejsce na dysku, a wydajność wydobywania i aktualizacji danych spada. Przez „nadmuchiwanie” rozumiem nieefektywne utrzymywanie struktury indeksowej. Może to być — a może nie być — związane z nieużywanymi krotkami, które są usuwane VACUUM (dzięki za informacje dla Petera Geoghana (Peter Geoghegan)). Nadmuchiwanie indeksu jest szczególnie zauważalne w obciążeniach, w których indeks jest aktywnie zmieniany.

PostgreSQL 12 znacząco poprawia wydajność indeksów B-drzew, a eksperymenty z testami typu TPC-C pokazały, że teraz wykorzystanie miejsca jest średnio o 40% mniejsze. Teraz spędzamy mniej czasu nie tylko na utrzymaniu indeksów B-drzew (to znaczy na operacjach zapisu), ale także na wydobywaniu danych, ponieważ indeksy stały się znacznie mniejsze.

Aplikacje, które aktywnie aktualizują swoje tabele — zazwyczaj są to aplikacje OLTP (przetwarzanie transakcji w czasie rzeczywistym) — będą znacznie efektywniej wykorzystywać dysk i obsługiwać zapytania. Im więcej miejsca na dysku, tym więcej przestrzeni ma baza danych na rozwój bez modernizacji infrastruktury.

Niektóre strategie modernizacji wymagają rekonstrukcji indeksów B-drzew, aby skorzystać z tych korzyści (na przykład, pg_upgrade nie zrekonstruuje indeksów automatycznie). W poprzednich wersjach PostgreSQL rekonstrukcja dużych indeksów w tabelach prowadziła do znacznych przestojów, ponieważ w tym czasie nie można było wprowadzać zmian. Jednak w PostgreSQL 12 jest jeszcze jedna świetna funkcja: teraz można rekonstrukcję indeksów wykonywać równolegle poleceniem REINDEX CONCURRENTLY, aby całkowicie uniknąć przestojów.

W PostgreSQL 12 wprowadzono również inne ulepszenia infrastruktury indeksowania. Jeszcze jedna rzecz, która nie obeszła się bez magii, to dziennik rejestracji wcześniejszej, zwany też WAL (journal write-ahead). Dziennik rejestracji wcześniejszej zapisuje każdą transakcję w PostgreSQL na wypadek awarii i replikacji. Aplikacje korzystają z niego do archiwizacji i odzyskiwania z momentu w czasie. Oczywiście, dziennik rejestracji wcześniejszej jest zapisywany na dysku, co może wpłynąć na wydajność.

W PostgreSQL 12 zmniejszyły się koszty zapisów WAL, które są tworzone przez indeksy GiST, GIN i SP-GiST podczas budowy indeksu. To przynosi kilka wymiernych korzyści: zapisy WAL zajmują mniej miejsca na dysku, a dane są szybciej odtwarzane, na przykład podczas odzyskiwania po awarii lub przywracania do określonego momentu. Jeśli w swoich aplikacjach używasz takich indeksów (na przykład aplikacje geoprzy przestrzenne oparte na PostGIS intensywnie korzystają z indeksu GiST), to jest to kolejna funkcja, która znacznie poprawi działanie bez żadnych wysiłków z twojej strony.

Partycjonowanie — więcej, lepiej, szybciej

W PostgreSQL 10 pojawiło się deklaratywne partycjonowanie. W PostgreSQL 11 stało się znacznie łatwiejsze w użyciu. W PostgreSQL 12 można zmieniać skalę sekcji.

W PostgreSQL 12 wydajność systemu partycjonowania znacznie się poprawiła, zwłaszcza jeśli w tabeli znajduje się tysiące sekcji. Na przykład, jeśli zapytanie dotyczy tylko kilku sekcji w tabeli, w której jest ich tysiące, to będzie wykonywane znacznie szybciej. Wydajność poprawiła się nie tylko dla takich typów zapytań. Zauważysz również, jak przyspieszyły operacje INSERT w tabelach z wieloma sekcjami.

Zapis danych za pomocą COPY — nota bene, to doskonały sposób masowej ładowania danych i oto przykład przyjęcia JSON — w partycjonowanych tabelach w PostgreSQL 12 również stało się bardziej efektywne. Z COPY wszystko już było szybkie, a w PostgreSQL 12 po prostu lata.

Dzięki tym zaletom w PostgreSQL można przechowywać zestawy danych jeszcze większych rozmiarów, a ich wydobycie stało się prostsze. I to bez żadnego wysiłku z twojej strony. Jeśli aplikacja ma wiele sekcji, na przykład, zapisuje dane z czasowych szeregów, prosta aktualizacja znacznie poprawi jej wydajność.

I chociaż ta poprawa nie jest całkiem z kategorii „aktualizowałem i cieszę się”, w PostgreSQL 12 można tworzyć klucze obce, które odnoszą się do partycjonowanych tabel, aby praca z partycjonowaniem sprawiała tylko przyjemność.

Zapytania WITH stały się znacznie lepsze

Kiedy zastosowano łaty do wbudowanych ogólnych wyrażeń tabelarycznych (to są CTE, to są zapytania WITH), nie mogłem się doczekać, aby napisać artykuł o tym, jak ucieszyli się programiści aplikacji z PostgreSQL. To jedna z tych funkcji, które przyspieszą aplikację. Jeśli oczywiście korzystasz z CTE.

Często zauważam, że nowicjusze w SQL lubią używać CTE: jeśli napiszesz je w określony sposób, od razu czujesz, że piszesz program imperatywny. Osobiście uwielbiałem przepisywać te zapytania, by obejść się bez CTE i zwiększyć wydajność. Dziś wszystko się zmieniło.

PostgreSQL 12 pozwala na osadzenie pewnego typu CTE bez efektów ubocznych (SELECT), który jest używany tylko raz, bliżej końca zapytania. Gdybym prowadził statystyki zapytań z CTE, które przepisywałem, większość z nich trafiłaby do tej kategorii. Pomaga to programistom pisać zrozumiały kod, który teraz działa jeszcze szybciej.

Co więcej, PostgreSQL 12 optymalizuje wykonanie SQL samodzielnie, nie musisz nic robić. I choć teraz pewnie nie muszę optymalizować takich zapytań, cieszy mnie, że PostgreSQL nadal pracuje nad optymalizacją zapytań.

Just-in-Time (JIT) — teraz domyślnie

W systemach PostgreSQL 12 z obsługą LLVM kompilacja JIT włączona jest domyślnie. Po pierwsze, zyskujesz wsparcie JIT dla niektórych operacji wewnętrznych, a po drugie, zapytania z wyrażeniami (najprostszy przykład — x + y) w listach wyboru (które występują po SELECT), agregatach, wyrażeniach w klauzulach WHERE i innych mogą wykorzystywać JIT dla poprawy wydajności.

Ponieważ JIT jest włączony w PostgreSQL 12 domyślnie, wydajność poprawi się sama, ale zalecam przetestowanie aplikacji w PostgreSQL 11, gdzie JIT dopiero się pojawił, aby zmierzyć wydajność zapytań i sprawdzić, czy wymagają jakichś ustawień.

A co z pozostałymi nowymi funkcjami PostgreSQL 12?

W PostgreSQL 12 jest mnóstwo nowych ciekawych funkcji — od możliwości przeszukiwania danych JSON za pomocą standardowych wyrażeń SQL/JSON, po wieloczynnikową autoryzację z opcją clientcert=verify-full, kolumn wirtualnych i wiele innych. To wystarczy na osobny post.

Podobnie jak PostgreSQL 10, PostgreSQL 12 poprawi ogólną wydajność już po aktualizacji. Oczywiście możesz mieć swój sposób — przetestuj aplikację w podobnych warunkach w systemie produkcyjnym, zanim włączysz usprawnienia, jak zrobiłem to z PostgreSQL 10. Nawet jeśli PostgreSQL 12 jest obecnie stabilniejszy, niż się spodziewałem, nie leniw się, by solidnie przetestować aplikacje przed ich wprowadzeniem do produkcji.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster