Zobacz wypełnianie bazy danych w podręczniku PostgreSQL, doskonały jak zwykle artykuł depesz na ten temat i to pytanie SO.
(Zauważ, że ta odpowiedź dotyczy zbiorczego ładowania danych do istniejącej bazy danych lub tworzenia nowej. Jeśli interesuje Cię wydajność przywracania bazy danych za pomocą pg_restore
lub psql
wykonanie pg_dump
wyjście, wiele z tego nie ma zastosowania, ponieważ pg_dump
i pg_restore
już robi takie rzeczy, jak tworzenie wyzwalaczy i indeksów po zakończeniu przywracania schematu+danych) .
Jest wiele do zrobienia. Idealnym rozwiązaniem byłoby zaimportowanie do UNLOGGED
tabeli bez indeksów, a następnie zmień ją na logowaną i dodaj indeksy. Niestety w PostgreSQL 9.4 nie ma obsługi zmiany tabel z UNLOGGED
do zalogowania. 9.5 dodaje ALTER TABLE ... SET LOGGED
aby pozwolić ci to zrobić.
Jeśli możesz przełączyć bazę danych w tryb offline w celu zbiorczego importu, użyj pg_bulkload
.
W przeciwnym razie:
-
Wyłącz wszystkie wyzwalacze na stole
-
Upuść indeksy przed rozpoczęciem importu, a następnie utwórz je ponownie. (To zajmuje dużo mniej czasu na zbudowanie indeksu w jednym przebiegu niż na stopniowe dodawanie do niego tych samych danych, a wynikowy indeks jest znacznie bardziej zwarty).
-
W przypadku importowania w ramach pojedynczej transakcji można bezpiecznie usunąć ograniczenia klucza obcego, wykonać import i ponownie utworzyć ograniczenia przed zatwierdzeniem. Nie rób tego, jeśli import jest podzielony na wiele transakcji, ponieważ możesz wprowadzić nieprawidłowe dane.
-
Jeśli to możliwe, użyj
KOPIUJ
zamiastWSTAW
s -
Jeśli nie możesz użyć
KOPIUJ
rozważ użycie wielowartościowychINSERT
jeśli jest to praktyczne. Wydaje się, że już to robisz. Nie próbuj wystawiać też wiele wartości w jednymVALUES
chociaż; te wartości muszą zmieścić się w pamięci kilka razy, więc utrzymuj je na poziomie kilkuset na instrukcję. -
Grupuj swoje wstawki w jawne transakcje, wykonując setki tysięcy lub miliony wstawek na transakcję. Nie ma praktycznego limitu AFAIK, ale przetwarzanie wsadowe pozwoli Ci naprawić błąd poprzez oznaczenie początku każdej partii w danych wejściowych. Ponownie, wydaje się, że już to robisz.
-
Użyj
synchronous_commit=off
i ogromnecommit_delay
aby zredukować koszty fsync(). Jednak niewiele to pomoże, jeśli podzielisz swoją pracę na duże transakcje. -
WSTAW
lubKOPIUJ
równolegle z kilku połączeń. Ile zależy od podsystemu dysku twojego sprzętu; z reguły potrzebujesz jednego połączenia na fizyczny dysk twardy, jeśli używasz bezpośrednio podłączonej pamięci masowej. -
Ustaw wysoki
max_wal_size
wartość (segmenty_punktu kontrolnego
w starszych wersjach) i włączlog_checkpoints
. Spójrz na logi PostgreSQL i upewnij się, że nie narzeka na zbyt częste występowanie punktów kontrolnych. -
Jeśli i tylko wtedy, gdy nie masz nic przeciwko utracie całego klastra PostgreSQL (bazy danych i innych w tym samym klastrze) na katastrofalne uszkodzenie, jeśli system ulegnie awarii podczas importu, możesz zatrzymać Pg, ustawić
fsync=off , uruchom Pg, wykonaj import, a następnie (koniecznie) zatrzymaj Pg i ustaw
fsync=on
ponownie. Zobacz Konfiguracja WAL. Nie rób tego, jeśli w dowolnej bazie danych w Twojej instalacji PostgreSQL są już jakieś dane, na których Ci zależy. Jeśli ustawiszfsync=off
możesz również ustawićfull_page_writes=off
; jeszcze raz pamiętaj, aby włączyć go ponownie po zaimportowaniu, aby zapobiec uszkodzeniu bazy danych i utracie danych. Zobacz nietrwałe ustawienia w podręczniku Pg.
Powinieneś także przyjrzeć się tuningowi swojego systemu:
-
Używaj dobrej jakości Dyski SSD do przechowywania jak najwięcej. Dobre dyski SSD z niezawodnymi, chronionymi przed zasilaniem pamięciami podręcznymi typu write-back sprawiają, że współczynniki realizacji są niewiarygodnie szybsze. Są mniej korzystne, jeśli zastosujesz się do powyższych rad — co zmniejsza liczbę wymazań dysku / liczbę
fsync()
s - ale nadal może być dużą pomocą. Nie używaj tanich dysków SSD bez odpowiedniej ochrony przed awarią zasilania, chyba że nie zależy Ci na przechowywaniu danych. -
Jeśli używasz macierzy RAID 5 lub RAID 6 do bezpośredniego podłączania pamięci masowej, przestań teraz. Utwórz kopię zapasową danych, zmień strukturę macierzy RAID na RAID 10 i spróbuj ponownie. RAID 5/6 są beznadziejne dla wydajności zapisu masowego – chociaż dobry kontroler RAID z dużą pamięcią podręczną może pomóc.
-
Jeśli masz możliwość korzystania ze sprzętowego kontrolera RAID z dużą, podtrzymywaną bateryjnie pamięcią podręczną zapisu zwrotnego, może to naprawdę poprawić wydajność zapisu w przypadku obciążeń z dużą liczbą zatwierdzeń. Nie pomaga to tak bardzo, jeśli używasz zatwierdzania asynchronicznego z commit_delay lub jeśli wykonujesz mniej dużych transakcji podczas ładowania zbiorczego.
-
Jeśli to możliwe, przechowuj WAL (
pg_wal
lubpg_xlog
w starszych wersjach) na osobnym dysku/macierzy dyskowej. Nie ma sensu używać osobnego systemu plików na tym samym dysku. Ludzie często decydują się na użycie pary RAID1 dla WAL. Ponownie, ma to większy wpływ na systemy z wysokimi wskaźnikami zatwierdzania i ma niewielki wpływ, jeśli używasz nierejestrowanej tabeli jako miejsca docelowego ładowania danych.
Możesz być również zainteresowany Optymalizacją PostgreSQL do szybkiego testowania.