Przechodzę na PostgreSQL z SQLite dla typowej aplikacji Railsowej.
Problem polega na tym, że działające specyfikacje stały się wolne z PG.
Na SQLite zajęło ~ 34 sekund, na PG ~ 76 sekund, czyli ponad 2x wolniej .
Więc teraz chcę zastosować pewne techniki, aby dostosować wydajność specyfikacji do SQLite bez modyfikacji kodu (najlepiej po prostu ustawiając opcje połączenia, co prawdopodobnie nie jest możliwe).
Kilka oczywistych rzeczy z góry mojej głowy to:
- Dysk RAM (dobrze byłoby zobaczyć dobrą konfigurację z RSpec na OSX)
- Niezalogowane tabele (czy można je zastosować do całej bazy danych, aby nie zmieniać wszystkich skryptów?)
Jak zapewne zrozumiałeś, nie dbam o niezawodność i resztę (DB jest tutaj czymś wyjątkowym).
Muszę jak najlepiej wykorzystać PG i zrobić to tak szybko, jak to możliwe .
Najlepsza odpowiedź najlepiej opisałaby sztuczki związane z robieniem tego, ustawienie i wady tych sztuczek.
AKTUALIZACJA: fsync = off
+ full_page_writes = off
tylko skrócił czas do ~ 65 sekund (~ -16 sekund). Dobry początek, ale daleko od celu 34.
UPDATE 2: I próbował dysku wykorzystanie pamięci RAM , ale wzrost wydajności był obrębie marginesu błędu. Nie wydaje się więc tego warte.
AKTUALIZACJA 3: * Znalazłem największe wąskie gardło, a teraz moje specyfikacje działają tak szybko, jak te SQLite.
Problem polegał na oczyszczeniu bazy danych, które spowodowało obcięcie . Najwyraźniej SQLite jest tam zbyt szybki.
Aby to naprawić, otwieram transakcję przed każdym testem i wycofuję ją na końcu.
Niektóre liczby dla ~ 700 testów.
- Obcięcie: SQLite - 34s, PG - 76s.
- Transakcja: SQLite - 17s, PG - 18s.
2x wzrost prędkości dla SQLite. 4x wzrost prędkości dla PG.
źródło
Odpowiedzi:
Po pierwsze, zawsze używaj najnowszej wersji PostgreSQL. Poprawki wydajności zawsze nadchodzą, 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 skanowanie tylko do indeksu. Należy zawsze śledzić nawet niewielkie wydania; zobacz zasady dotyczące wersji .Nie
Czy NIE umieścić tabel na ramdysku lub innego przedmiotu trwałego składowania .
W przypadku utraty obszaru tabel cała baza danych może zostać uszkodzona i utrudniona w użyciu bez znacznej pracy. Ma to bardzo małą zaletę w porównaniu do zwykłego używania
UNLOGGED
tabel i posiadania dużej ilości pamięci RAM na pamięć podręczną.Jeśli naprawdę chcesz systemu opartego na ramdysku,
initdb
to całkowicie nowy klaster na ramdysku,initdb
wprowadzając nową instancję PostgreSQL na ramdysku, więc masz całkowicie jednorazową instancję PostgreSQL.Konfiguracja serwera PostgreSQL
Podczas testowania możesz skonfigurować serwer pod kątem nietrwałej, ale szybszej pracy .
Jest to jedno z niewielu dopuszczalnych zastosowań
fsync=off
ustawienia w PostgreSQL. To ustawienie w zasadzie mówi PostgreSQL, aby nie zawracał sobie głowy zamówionymi zapisami lub innymi nieprzyjemnymi kwestiami związanymi z ochroną integralności danych i zabezpieczeniem przed awariami, 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
produkcji, chyba że używasz PG jako tymczasowej bazy danych dla danych, które możesz ponownie wygenerować z innego miejsca. Jeśli i tylko jeśli chcesz wyłączyć fsync, możesz go równieżfull_page_writes
wyłączyć, ponieważ nie przynosi to już żadnego pożytku. Uważajfsync=off
ifull_page_writes
stosuj na poziomie klastra , aby wpływały one na wszystkie bazy danych w Twojej instancji PostgreSQL.Do użytku produkcyjnego możesz użyć
synchronous_commit=off
i ustawićcommit_delay
, ponieważ uzyskasz wiele takich samych korzyści, jakfsync=off
bez ogromnego ryzyka uszkodzenia danych. Jeśli włączysz zatwierdzanie asynchroniczne, masz małe okno utraty ostatnich danych - ale to wszystko.Jeśli masz możliwość nieznacznej zmiany DDL, możesz także użyć
UNLOGGED
tabel w Pg 9.1+, aby całkowicie uniknąć rejestrowania WAL i uzyskać rzeczywiste przyspieszenie kosztem usunięcia tabel w przypadku awarii serwera. Nie ma opcji konfiguracji, aby wszystkie tabele były niezalogowane, należy je ustawić podczasCREATE 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 elementy, które musisz zachować bezpieczeństwo.Sprawdź swoje dzienniki i sprawdź, czy otrzymujesz ostrzeżenia o zbyt wielu punktach kontrolnych. Jeśli tak, powinieneś zwiększyć swoje punkty kontrolne . Możesz także dostroić swój punkt kontrolny_wykonanie_przeprowadzania, aby wygładzić zapisy.
Dostosuj
shared_buffers
do obciążenia. Jest to zależne od systemu operacyjnego, zależy od tego, co dzieje się na twoim komputerze i wymaga pewnych prób i błędów. Domyślne są bardzo konserwatywne. Może być konieczne zwiększenie maksymalnego limitu pamięci współużytkowanej przez system operacyjny, jeśli zwiększyszshared_buffers
w PostgreSQL 9.2 i niższych; W wersji 9.3 i nowszych zmieniono sposób, w jaki korzystają z pamięci współdzielonej, aby tego uniknąć.Jeśli używasz tylko kilku połączeń, które wykonują dużo pracy, zwiększ
work_mem
je , aby dać im więcej pamięci RAM na różne rodzaje itp. Uważaj, że zbyt wysokiework_mem
ustawienie może powodować problemy z brakiem pamięci, ponieważ nie jest to zależne od rodzaju na połączenie, więc jedno zapytanie może mieć wiele zagnieżdżonych rodzajów. Naprawdę musisz tylko zwiększyć,work_mem
jeśli widzisz sortowania przelewające się na dyskEXPLAIN
lub zalogowane zlog_temp_files
ustawieniem (zalecane), ale wyższa wartość może również pozwolić Pg wybrać inteligentniejsze plany.Jak powiedział inny plakat tutaj, rozsądnie jest umieścić xlog i główne tabele / indeksy na osobnych dyskach twardych, jeśli to możliwe. Oddzielne partycje są dość bezcelowe, naprawdę chcesz osobnych dysków. Ta separacja przynosi znacznie mniejsze korzyści, jeśli używasz,
fsync=off
i prawie żadna, jeśli używaszUNLOGGED
tabel.Na koniec dostosuj swoje zapytania. Upewnij się, że
random_page_cost
iseq_page_cost
odzwierciedlają wydajność systemu, zapewnienia bezpieczeństwaeffective_cache_size
jest prawidłowa, itd. ZastosowanieEXPLAIN (BUFFERS, ANALYZE)
do zbadania indywidualnych planów kwerend i włączauto_explain
moduł dotyczący 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 interesujące móc to zrobić. Zastanów się nad pytaniem na liście mailingowej PostgreSQL.Strojenie systemu operacyjnego hosta
Istnieje również możliwość dostrajania na poziomie systemu operacyjnego. Najważniejsze, co możesz zrobić, to przekonać system operacyjny, aby nie czyścił agresywnie zapisów na dysk, ponieważ tak naprawdę nie obchodzi Cię, kiedy / jeśli trafią na dysk.
W Linuksie można sterować tym z wirtualnego podsystemu pamięci „s
dirty_*
ustawień, takich jakdirty_writeback_centisecs
.Jedynym problemem związanym z dostrajaniem ustawień zapisu zwrotnego, które są zbyt luźne, jest to, że opróżnianie przez inny program może powodować opróżnianie wszystkich zgromadzonych buforów PostgreSQL, powodując duże przeciągnięcia, podczas gdy wszystko blokuje zapis. Możesz to złagodzić, uruchamiając PostgreSQL na innym systemie plików, ale niektóre zmiany mogą być na poziomie urządzenia lub całego hosta, a nie systemu plików, więc nie możesz na tym polegać.
To dostrajanie naprawdę wymaga zabawy z ustawieniami, aby zobaczyć, co działa najlepiej dla twojego obciążenia.
W nowszych jądrach możesz to zapewnić
vm.zone_reclaim_mode
jest ustawiony na zero, ponieważ może to powodować poważne problemy z wydajnością w systemach NUMA (większość systemów obecnie) z powodu interakcji z zarządzaniem PostgreSQLshared_buffers
.Dostosowywanie zapytań i obciążenia
Są to rzeczy, które wymagają zmian kodu; mogą ci nie odpowiadać. Niektóre rzeczy możesz zastosować.
Jeśli nie grupujesz pracy w większe transakcje, zacznij. Wiele małych transakcji jest drogich, więc powinieneś grupować rzeczy, gdy tylko jest to możliwe i praktyczne. Jeśli używasz zatwierdzenia asynchronicznego, jest to mniej ważne, ale nadal wysoce zalecane.
O ile to możliwe, używaj tabel tymczasowych. Nie generują one ruchu WAL, więc są znacznie szybsze w przypadku wstawek i aktualizacji. Czasami warto schować kilka danych do tabeli tymczasowej, manipulować nimi w dowolny sposób, a następnie
INSERT INTO ... SELECT ...
skopiować je do tabeli końcowej. Pamiętaj, że tabele tymczasowe są na sesję; jeśli twoja sesja się skończy lub stracisz połączenie, tabela tymczasowa zniknie i żadne inne połączenie nie będzie widzieć zawartości tabel tymczasowych.Jeśli korzystasz z PostgreSQL 9.1 lub nowszego, możesz użyć
UNLOGGED
tabel dla danych, które możesz stracić, np. Stanu sesji. Są one widoczne w różnych sesjach i zachowywane między połączeniami. Są one obcinane, jeśli serwer zostanie wyłączony nieczysto, więc nie można ich użyć do niczego, czego nie można odtworzyć, ale świetnie nadają się do pamięci podręcznych, zmaterializowanych widoków, tabel stanu itp.Ogólnie nie
DELETE FROM blah;
.TRUNCATE TABLE blah;
Zamiast tego użyj ; jest o wiele szybsze, gdy zrzucasz wszystkie wiersze w tabeli.TRUNCATE
Jeśli możesz, obetnij wiele tabel w jednym wywołaniu. Jest jednak zastrzeżenie, jeśli robisz wieleTRUNCATES
małych stolików w kółko; patrz: Postgresql Prędkość obcięciaJeśli nie masz indeksów na klucze obce,
DELETE
s obejmujących klucze podstawowe, do których odwołują się te klucze obce, będą strasznie wolne. Pamiętaj, aby utworzyć takie indeksy, jeśli kiedykolwiek będziesz tego oczekiwał naDELETE
podstawie tabel (y). Indeksy nie są wymagane dlaTRUNCATE
.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 skanom indeksów bitmapowych je połączyć, zamiast utrzymywać zbyt wiele ogromnych, drogich indeksów wielokolumnowych. Tam, gdzie wymagane są indeksy, spróbuj najpierw wypełnić tabelę, a następnie utwórz indeksy na końcu.
Sprzęt komputerowy
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, tym szybciej możesz uzyskać więcej miejsca. Nawet tani dysk SSD ma ogromną różnicę w stosunku do wirującej rdzy. Nie ufaj taniej dyskom SSD do produkcji, często nie są odporne na awarie i mogą zjadać twoje dane.
Uczenie się
Książka Grega Smitha, PostgreSQL 9.0 High Performance pozostaje aktualna, mimo że odnosi się do nieco starszej wersji. Powinno to być przydatne odniesienie.
Dołącz do ogólnej listy mailingowej PostgreSQL i śledź ją.
Czytanie:
źródło
Użyj innego układu dysku:
poprawki w postgresql.conf:
źródło
fsync=off
, umieszczenie pg_xlog na osobnym dysku już się nie poprawi.