PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak przyspieszyć działanie wstawiania w PostgreSQL

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 zamiast WSTAW s

  • Jeśli nie możesz użyć KOPIUJ rozważ użycie wielowartościowych INSERT jeśli jest to praktyczne. Wydaje się, że już to robisz. Nie próbuj wystawiać też wiele wartości w jednym VALUES 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 ogromne commit_delay aby zredukować koszty fsync(). Jednak niewiele to pomoże, jeśli podzielisz swoją pracę na duże transakcje.

  • WSTAW lub KOPIUJ 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łącz log_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 ustawisz fsync=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 lub pg_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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Generuj serie dat — używając typu daty jako danych wejściowych

  2. Czy jesteśmy gotowi na Nordic PGDay?

  3. Wdrażanie i konserwacja PostgreSQL z Ansible

  4. Jak dodać warunkowy unikalny indeks w PostgreSQL

  5. PostgreSQL DATEADD() Odpowiednik