Po pierwsze, zawsze używaj najnowszej wersji PostgreSQL. Zawsze nadchodzą ulepszenia wydajności, więc prawdopodobnie tracisz czas, jeśli dostrajasz starą wersję. Na przykład PostgreSQL 9.2 znacząco poprawia szybkość TRUNCATE
i oczywiście dodaje tylko skany indeksu. Nawet drobne wydania powinny być zawsze przestrzegane; zobacz zasady dotyczące wersji.
Nie wolno
NIE umieść obszar tabel na RAMdysku lub innej nietrwałej pamięci masowej.
Jeśli stracisz obszar tabel, cała baza danych może zostać uszkodzona i trudna w użyciu bez znacznego nakładu pracy. Jest to bardzo mała zaleta w porównaniu do zwykłego używania UNLOGGED
tabele i mimo wszystko dużo pamięci RAM na pamięć podręczną.
Jeśli naprawdę chcesz systemu opartego na ramdysku, initdb
zupełnie nowy klaster na ramdysku autorstwa initdb
nowej instancji PostgreSQL na ramdysku, dzięki czemu masz całkowicie jednorazową instancję PostgreSQL.
Konfiguracja serwera PostgreSQL
Podczas testowania możesz skonfigurować serwer do nietrwałego, ale szybszego działania.
Jest to jedno z jedynych dopuszczalnych zastosowań fsync=off
ustawienie w PostgreSQL. To ustawienie prawie mówi PostgreSQL, aby nie zawracał sobie głowy uporządkowanymi zapisami lub innymi paskudnymi funkcjami ochrony integralności danych i bezpieczeństwa w razie awarii, dając mu pozwolenie na całkowite zniszczenie danych w przypadku utraty zasilania lub awarii systemu operacyjnego.
Nie trzeba dodawać, że nigdy nie należy włączać fsync=off
w środowisku produkcyjnym, chyba że używasz Pg jako tymczasowej bazy danych dla danych, które możesz ponownie wygenerować z innego miejsca. Jeśli i tylko wtedy, gdy chcesz wyłączyć fsync, możesz również włączyć full_page_writes
zgaś, bo to już nie przynosi żadnego pożytku. Uważaj, że fsync=off
i full_page_writes
złóż wniosek w klastrze poziom, więc wpływają na wszystkie bazy danych w twojej instancji PostgreSQL.
Do użytku produkcyjnego możesz ewentualnie użyć synchronous_commit=off
i ustaw commit_delay
, ponieważ uzyskasz wiele takich samych korzyści jak fsync=off
bez ogromnego ryzyka uszkodzenia danych. Masz małe okno na utratę ostatnich danych, jeśli włączysz zatwierdzanie asynchroniczne - ale to wszystko.
Jeśli masz możliwość nieznacznej zmiany DDL, możesz również użyć UNLOGGED
tabele na stronie 9.1+, aby całkowicie uniknąć rejestrowania WAL i uzyskać prawdziwy wzrost prędkości kosztem usunięcia tabel w przypadku awarii serwera. Nie ma opcji konfiguracyjnej, aby wszystkie tabele były wylogowywane, należy to ustawić podczas CREATE TABLE
. Oprócz tego, że jest dobry do testowania, jest to przydatne, jeśli masz tabele pełne wygenerowanych lub nieistotnych danych w bazie danych, która w przeciwnym razie zawiera rzeczy, których potrzebujesz, aby być bezpiecznym.
Sprawdź swoje dzienniki i zobacz, czy otrzymujesz ostrzeżenia o zbyt wielu punktach kontrolnych. Jeśli tak, powinieneś zwiększyć swój checkpoint_segments. Możesz także dostroić swój punkt kontrolny_completion_target, aby płynnie pisać.
Dostrój shared_buffers
aby dopasować się do obciążenia pracą. Jest to zależne od systemu operacyjnego, zależy od tego, co jeszcze dzieje się z twoim komputerem i wymaga pewnych prób i błędów. Wartości domyślne są niezwykle konserwatywne. Może być konieczne zwiększenie maksymalnego limitu pamięci współdzielonej systemu operacyjnego, jeśli zwiększysz wartość shared_buffers
na PostgreSQL 9.2 i niższych; 9.3 i nowsze zmieniły sposób, w jaki wykorzystują pamięć współdzieloną, aby tego uniknąć.
Jeśli używasz tylko kilku połączeń, które wykonują dużo pracy, zwiększ work_mem
aby dać im więcej pamięci RAM do zabawy itp. Uważaj, że zbyt wysoki work_mem
ustawienie może powodować problemy z brakiem pamięci, ponieważ dotyczy sortowania, a nie połączenia, więc jedno zapytanie może mieć wiele zagnieżdżonych sortowań. Ty tylko naprawdę trzeba zwiększyć work_mem
jeśli widzisz, że sorty rozlewają się na dysk w EXPLAIN
lub zalogowany za pomocą log_temp_files
ustawienie (zalecane), ale wyższa wartość może również pozwolić Pg na wybór mądrzejszych planów.
Jak powiedział inny autor, rozsądnie jest umieścić xlog i główne tabele/indeksy na osobnych dyskach twardych, jeśli to możliwe. Oddzielne partycje nie mają sensu, naprawdę potrzebujesz oddzielnych dysków. Ta separacja ma znacznie mniejsze korzyści, jeśli używasz fsync=off
i prawie żaden, jeśli używasz UNLOGGED
tabele.
Na koniec dostosuj swoje zapytania. Upewnij się, że Twój random_page_cost
i seq_page_cost
odzwierciedlają wydajność twojego systemu, upewnij się, że Twój effective_cache_size
jest poprawne itp. Użyj EXPLAIN (BUFFERS, ANALYZE)
aby zbadać poszczególne plany zapytań i włączyć auto_explain
moduł do zgłaszania wszystkich powolnych zapytań. Często można znacznie poprawić wydajność zapytań, po prostu tworząc odpowiedni indeks lub dostosowując parametry kosztów.
AFAIK nie ma możliwości ustawienia całej bazy danych lub klastra jako UNLOGGED
. Byłoby ciekawie móc to zrobić. Zastanów się nad pytaniem na liście mailingowej PostgreSQL.
Dostrajanie systemu operacyjnego hosta
Istnieje również możliwość dostrojenia na poziomie systemu operacyjnego. Najważniejszą rzeczą, którą możesz chcieć zrobić, to przekonać system operacyjny, aby nie wyrzucał agresywnie zapisów na dysk, ponieważ naprawdę nie obchodzi cię, kiedy/czy dostaną się na dysk.
W Linuksie możesz to kontrolować za pomocą dirty_*
podsystemu pamięci wirtualnej ustawienia, takie jak dirty_writeback_centisecs
.
Jedynym problemem związanym ze strojeniem ustawień zapisu zwrotnego, aby były zbyt słabe, jest to, że opróżnianie przez inny program może spowodować opróżnienie wszystkich nagromadzonych buforów PostgreSQL, powodując duże blokady, podczas gdy wszystko blokuje się podczas zapisu. Możesz to złagodzić, uruchamiając PostgreSQL w innym systemie plików, ale niektóre opróżnienia mogą być na poziomie urządzenia lub całego hosta, a nie na poziomie systemu plików, więc nie możesz na tym polegać.
To dostrojenie naprawdę wymaga zabawy z ustawieniami, aby zobaczyć, co najlepiej pasuje do Twojego obciążenia.
W nowszych jądrach możesz chcieć upewnić się, że vm.zone_reclaim_mode
jest ustawiona na zero, ponieważ może powodować poważne problemy z wydajnością w systemach NUMA (większość systemów w dzisiejszych czasach) ze względu na interakcje ze sposobem, w jaki PostgreSQL zarządza shared_buffers
.
Dostrajanie zapytań i obciążenia
To są rzeczy, które wymagają zmian w kodzie; mogą ci nie odpowiadać. Niektóre to rzeczy, które możesz zastosować.
Jeśli nie dzielisz pracy na większe transakcje, zacznij. Wiele małych transakcji jest drogich, więc powinieneś robić partie, kiedy tylko jest to możliwe i praktyczne. Jeśli używasz zatwierdzania asynchronicznego, jest to mniej ważne, ale nadal wysoce zalecane.
W miarę możliwości używaj tabel tymczasowych. Nie generują ruchu WAL, więc są znacznie szybsze w przypadku wstawiania i aktualizowania. Czasami warto wrzucić garść danych do tabeli tymczasowej, manipulując nią w dowolny sposób, a następnie wykonać INSERT INTO ... SELECT ...
skopiować go do stołu finałowego. Zwróć uwagę, że tabele tymczasowe dotyczą sesji; jeśli sesja zakończy się lub utracisz połączenie, tabela tymczasowa zniknie i żadne inne połączenie nie będzie mogło zobaczyć zawartości tabel tymczasowych sesji.
Jeśli używasz PostgreSQL 9.1 lub nowszego, możesz użyć UNLOGGED
tabele danych, które możesz utracić, np. stan sesji. Są one widoczne w różnych sesjach i zachowywane między połączeniami. Są one obcinane, jeśli serwer zostanie zamknięty w nieczysty sposób, więc nie można ich użyć do niczego, czego nie można odtworzyć, ale doskonale nadają się do pamięci podręcznych, widoków zmaterializowanych, tabel stanów itp.
Ogólnie rzecz biorąc, nie DELETE FROM blah;
. Użyj TRUNCATE TABLE blah;
zamiast; jest dużo szybciej, gdy zrzucasz wszystkie wiersze w tabeli. Obetnij wiele tabel w jednym TRUNCATE
zadzwoń, jeśli możesz. Istnieje zastrzeżenie, jeśli wykonujesz wiele TRUNCATES
za to małych stolików w kółko; zobacz:Szybkość obcinania Postgresql
Jeśli nie masz indeksów kluczy obcych, DELETE
Klucze podstawowe, do których odwołują się te klucze obce, będą strasznie powolne. Pamiętaj, aby utworzyć takie indeksy, jeśli kiedykolwiek spodziewasz się DELETE
z przywołanej tabeli (tabeli). Indeksy nie są wymagane dla TRUNCATE
.
Nie twórz indeksów, których nie potrzebujesz. Każdy indeks ma koszt utrzymania. Spróbuj użyć minimalnego zestawu indeksów i pozwól skanowaniu indeksów bitmapowych połączyć je, zamiast utrzymywać zbyt wiele ogromnych, kosztownych wielokolumnowych indeksów. Tam, gdzie indeksy są wymagane, spróbuj najpierw wypełnić tabelę, a następnie utwórz indeksy na końcu.
Sprzęt
Posiadanie wystarczającej ilości pamięci RAM do przechowywania całej bazy danych to ogromna wygrana, jeśli możesz nią zarządzać.
Jeśli nie masz wystarczającej ilości pamięci RAM, im szybsze przechowywanie, tym lepiej. Nawet tani dysk SSD robi ogromną różnicę w stosunku do wirującej rdzy. Nie ufaj jednak tanim dyskom SSD do produkcji, często nie są one bezpieczne w przypadku awarii i mogą pochłaniać Twoje dane.
Nauka
Książka Grega Smitha, PostgreSQL 9.0 High Performance pozostaje aktualna, mimo że odnosi się do nieco starszej wersji. Powinno to być przydatne źródło informacji.
Dołącz do ogólnej listy mailingowej PostgreSQL i podążaj za nią.
Czytanie:
- Dostrajanie serwera PostgreSQL - Wiki PostgreSQL
- Liczba połączeń z bazą danych - Wiki PostgreSQL