Muszę programowo wstawić 10 milionów rekordów do bazy danych Postgres. Obecnie wykonuję 1000 instrukcji wstawiania w jednym „zapytaniu”.
Czy istnieje lepszy sposób, aby to zrobić, jakąś masową instrukcję wstawiania, o której nie wiem?
postgresql
bulkinsert
Popiół
źródło
źródło
Istnieje alternatywa dla korzystania z COPY, która jest składnią wielu wartości, którą obsługuje Postgres. Z dokumentacji :
Powyższy kod wstawia dwa wiersze, ale możesz go dowolnie rozszerzyć, dopóki nie osiągniesz maksymalnej liczby przygotowanych tokenów instrukcji (może to być 999 USD, ale nie jestem w 100% pewien). Czasami nie można korzystać z funkcji KOPIUJ i jest to godny zamiennik w takich sytuacjach.
źródło
Jednym ze sposobów przyspieszenia jest jawne wykonanie wielu wstawień lub kopii w ramach transakcji (powiedzmy 1000). Domyślnym zachowaniem Postgresa jest zatwierdzanie po każdej instrukcji, więc przez grupowanie zatwierdzeń można uniknąć pewnego narzutu. Jak mówi przewodnik w odpowiedzi Daniela, może być konieczne wyłączenie automatycznego zatwierdzania, aby to zadziałało. Zwróć również uwagę na komentarz na dole, który sugeruje zwiększenie wielkości buforów wal_buffers do 16 MB.
źródło
UNNEST
funkcja z tablicami może być używana wraz ze składnią multirow VALUES. Myślę, że ta metoda jest wolniejsza niż używanie,COPY
ale przydaje mi się w pracy z psycopg i python (pythonlist
przekazany nacursor.execute
pgARRAY
):bez
VALUES
użycia podselekcji z dodatkową kontrolą istnienia:ta sama składnia dla aktualizacji zbiorczych:
źródło
Możesz użyć opcji
COPY table TO ... WITH BINARY
„ nieco szybszej niż formaty tekstowe i CSV ”. Zrób to tylko wtedy, gdy masz miliony wierszy do wstawienia i nie masz problemów z danymi binarnymi.Oto przykładowy przepis w Pythonie, wykorzystujący psycopg2 z wejściem binarnym .
źródło
Zależy to głównie od (innej) aktywności w bazie danych. Takie operacje skutecznie zamrażają całą bazę danych na inne sesje. Innym zagadnieniem jest model danych i obecność ograniczeń, wyzwalaczy itp.
Moje pierwsze podejście to zawsze: utwórz tabelę (temp) o strukturze podobnej do tabeli docelowej (utwórz tabelę tmp AS wybierz * z celu, gdzie 1 = 0) i zacznij od odczytu pliku do tabeli temp. Następnie sprawdzam, co można sprawdzić: duplikaty, klucze, które już istnieją w celu itp.
Następnie wykonuję polecenie „do insert into target select * from tmp” lub podobne.
Jeśli to się nie powiedzie lub zajmie to zbyt długo, przerywam to i rozważam inne metody (tymczasowe usuwanie indeksów / ograniczeń itp.)
źródło
Zaimplementowałem bardzo szybki moduł ładujący Postgresq z natywnymi metodami libpq. Wypróbuj mój pakiet https://www.nuget.org/packages/NpgsqlBulkCopy/
źródło
Właśnie napotkałem ten problem i polecam csvsql ( wersje ) do masowego importu do Postgres. Aby wykonać wstawianie zbiorcze, którego po prostu
createdb
użyjeszcsvsql
, a następnie użyjesz , aby połączyć się z bazą danych i utworzyć indywidualne tabele dla całego folderu CSV.źródło
Plik zewnętrzny to najlepsze i typowe dane zbiorcze
Termin „dane zbiorcze” odnosi się do „dużej ilości danych”, więc naturalne jest używanie oryginalnych danych surowych , bez potrzeby przekształcania ich w SQL. Typowe pliki surowych danych dla „wstawiania zbiorczego” to CSV i JSON formaty .
Wkładka luzem z pewną transformacją
W aplikacjach ETL i procesach przetwarzania musimy zmienić dane przed ich wstawieniem. Tabela tymczasowa zajmuje (dużo) miejsca na dysku i nie jest to najszybszy sposób na zrobienie tego. PostgreSQL wrapper obcych dane (FDW) jest najlepszym wyborem.
Przykład CSV . Załóżmy, że
tablename (x, y, z)
plik SQL lub CSV jest podobnyMożesz użyć klasycznego kodu SQL,
COPY
aby załadować ( tak jak oryginalne dane)tmp_tablename
, wstawić przefiltrowane dane dotablename
... Ale, aby uniknąć zużycia dysku, najlepiej jest je pobrać bezpośrednio przezMusisz przygotować bazę danych dla FDW, a zamiast statycznego
tmp_tablename_fdw
możesz użyć funkcji, która ją generuje :Przykład JSON . Zestaw dwóch plików
myRawData1.json
iRanger_Policies2.json
może być spożywana przez:gdzie funkcja jsonb_read_files () odczytuje wszystkie pliki folderu zdefiniowane przez maskę:
Brak przesyłania strumieniowego gzip
Najczęstszą metodą „pobierania plików” (głównie w Big Data) jest zachowanie oryginalnego pliku w formacie gzip i przesłanie go za pomocą algorytmu przesyłania strumieniowego , wszystko, co może działać szybko i bez zużycia dysku w potokach unix:
Tak więc idealna (przyszłość) jest opcją formatu dla serwera
.csv.gz
.źródło