[PGSQL] Wyciskanie maksymalne inserty/sek
Bartek Siebab - 30-03-2006 00:13
[PGSQL] Wyciskanie maksymalne inserty/sek
Witam!
PostgreSQL 8.1.3 na win przyjmuje sobie insertami dane w jedną tabelkę. Tabelka jest prościutka - ma ledwie kilka pól varchar, int4, text Prawie wszystkie indeksowane. Postgres już potuningowany - sporo ramu mu dałem w bufory w różnych parametrach ale co ciekawe kompletnie nie wpłynęło to na przyśpieszenie insertowania. Podczas insertowania maszynka obciążona średnio około 20-30% procka. Dyski w zasadzie nie mają wiele do roboty - z ilości wpadających danych wychodzi że transfer na dysk jest poniżej 1MB/s więc do granicy wydajności dysku jeszcze sporo zostaje.
Wielkość inserta około 1-5 KB. Rzecz w tym że zależy mi na tym aby maksymalnie/sek ile się tylko da zapychać tych insertów w tabelę. Aktualnie baza od jednego klienta przyjmuje mi średnio 100 insertów/sekundę - co ciekawe nawet jak puszczę kilku naraz i tak każdemu idzie około 100/sekundę.
Pecety z których to leci mają obciążenie około 20% procesem wypychającym te dane w bazę (VS .NET 2005 + npgsql) na innej maszynie i także nie są wąskim gardłem bo puszczenie kilku procesów na pececie i tak daje od każdego po 100 insertów/sek.
Testowałem także zapychanie tego spod PgAdmin'a - max 120/sek. Czy ktoś ma pomysł co jeszcze ruszyć aby to przyśpieszyć? Ostatecznie mogę zrobić kilkanaście wątków w aplikacji tak by każdy z nich leciał po te 100/sek ale zastanawia mnie sam fakt że niby wszystkie maszynki się nudzą, sieć się nudzi a i tak leci średnio po 100 rekordów/sek. Mam do przewalania średnio 1.5 miliona rekordów dziennie z każdej maszynki a będzie ich pare dziesiątek więc zależy mi na speedzie...
PS. copy into odpada - to musi iść insertami.
-- ..---------- -------- ------ ---- ---- --- - -- - | Bartek `saphire` Siebab http://bartek.siebab.net
=?ISO-8859-2?Q?Micha=B3_Zaborowski?= - 30-03-2006 00:13
1. Jak robi się więcej niż jeden insert w połączeniu to należy to robić w transakcji. 2. Indeksy spowalniają modyfikowanie danych. 3. Wyzwalacze spowalniają modyfikowanie danych. 4. Wypadałoby podać konfigurację maszyny, liczbę klientów, i plik conf. Bez tego to jak wróżenie z fusów.
-- Pozdrawiam, Michał Zaborowski (TeXXaS)
Bartek Siebab - 31-03-2006 00:15
> Michał Zaborowski w dniu 2006-03-30 00:36 pisze: > 1. Jak robi się więcej niż jeden insert w połączeniu to > należy to robić w transakcji.
Teoretycznie mogę popaczkować po kilkaset w transakcję.
> 2. Indeksy spowalniają modyfikowanie danych.
Ale w moim przypadku przyśpieszają gigantycznie ich przeszukiwanie.
> 3. Wyzwalacze spowalniają modyfikowanie danych.
nie mam na tej tabeli triggerów
> 4. Wypadałoby podać konfigurację maszyny, liczbę klientów, > i plik conf. Bez tego to jak wróżenie z fusów.
Niezależnie od maszyny, czy to zwykły pecet czy kilku procesorowy Dell 2600 / 4800 w paroma GB ramu i wypaśnymi dyskami lub IBM eSeries podobny do della i tak idzie średnio 100 insertów/sek więc jak mówiłem nie widzę tu związku z wydajnością maszyny źródłowej/docelowej. Testy zrobione na _jednym_ połączeniu _jednego_ klienta jaki wielu klientów pokazują to samo: każdemu leci po 100 insertów/sek.
Cos mi się widzi że diabeł siedzi w samym tcp/ip i te opóźnienia generowane są zapewne przez stos sieciowy lub opóźnione potwierdzanie pakietów czy coś. Kiedyś podobny efekt był z Sambą i nagle'm
Dziś rzeźbnę aplikację by większymi paczkami w transakcjach wtykać te inserty i zobaczę czy cokolwiek to zmieni.
-- ..---------- -------- ------ ---- ---- --- - -- - | Bartek `saphire` Siebab http://bartek.siebab.net
=?ISO-8859-2?Q?Grzegorz_Prze=BCdziecki?= - 31-03-2006 00:16
Bartek Siebab wrote: > Witam! > > PostgreSQL 8.1.3 na win przyjmuje sobie insertami dane w jedną tabelkę.
/ciach/
akurat ostatnio czytam całą dokumentacje do PostgreSQL'a to jest temat poświecony twojemu zagadnieniu http://www.postgresql.org/docs/8.1/i.../populate.html
> PS. copy into odpada - to musi iść insertami. >
Best Regards
Bartek Siebab - 31-03-2006 00:16
> Grzegorz Przeździecki w dniu 2006-03-30 12:22 pisze:
> akurat ostatnio czytam całą dokumentacje do PostgreSQL'a > to jest temat poświecony twojemu zagadnieniu > http://www.postgresql.org/docs/8.1/i.../populate.html
Co do "prepare" to od początku tak mam zrobioną aplikację. Co do większych paczek insertów w jednej transakcji to przetestuję pod kątem ilości insertów w jednej transakcji ale jak ciut przerobię kod aplikacji. Co do copy - juz mówiłem - odpada. Co do wywalenie indeksów - także odpada. Obcych kluczy nie ma bo to jedna tabelka. Tuning pamięci zużywanej już zrobiony ale niewiele dał w tym przypadku, jedynie poprawiły się selekty po polach indeksowanych.
Jakieś inne propozycje?
-- ..---------- -------- ------ ---- ---- --- - -- - | Bartek `saphire` Siebab http://bartek.siebab.net
=?ISO-8859-2?Q?Micha=B3_Zaborowski?= - 01-04-2006 00:19
Dnia 2006-03-30 18:48, Użytkownik Bartek Siebab napisał :
> > Grzegorz Przeździecki w dniu 2006-03-30 12:22 pisze: > >> akurat ostatnio czytam całą dokumentacje do PostgreSQL'a >> to jest temat poświecony twojemu zagadnieniu >> http://www.postgresql.org/docs/8.1/i.../populate.html > > > Co do "prepare" to od początku tak mam zrobioną aplikację. > Co do większych paczek insertów w jednej transakcji to > przetestuję pod kątem ilości insertów w jednej transakcji > ale jak ciut przerobię kod aplikacji. > Co do copy - juz mówiłem - odpada. > Co do wywalenie indeksów - także odpada. > Obcych kluczy nie ma bo to jedna tabelka. > Tuning pamięci zużywanej już zrobiony ale niewiele dał > w tym przypadku, jedynie poprawiły się selekty po polach > indeksowanych. > > Jakieś inne propozycje? > Tak, proszę podać conf - bez tego nic się nie poradzi. Warto też napisać na listę mailową postgresa i opisać wszystko tak dokładnie jak się umie. No i tego confa też podać trzeba. Odpowiadają dość szybko - a że sami to piszą więc się znają ;) Jeden możliwy minus to to, że trzeba to zrobić po angielsku - ale jak rozumiem to nie problem.
-- Pozdrawiam, Michał Zaborowski (TeXXaS)
Filip Sielimowicz - 03-04-2006 00:07
Użytkownik "Bartek Siebab" <bs@vt.pl> napisał w wiadomości news:e0ejdm$mpm$1@atlantis.news.tpi.pl...
> Wielkość inserta około 1-5 KB. Rzecz w tym że zależy mi na tym aby > maksymalnie/sek ile się tylko da zapychać tych insertów w tabelę. > Aktualnie baza od jednego klienta przyjmuje mi średnio > 100 insertów/sekundę - co ciekawe nawet jak puszczę kilku naraz > i tak każdemu idzie około 100/sekundę.
Każdy pojedynczy insert ma 1-5 KB ? Czyli paczka 100 insertów ma 100-500 KB ? To już nie jest mało.
> Teoretycznie mogę popaczkować po kilkaset w transakcję.
W jaki sposób paczkujesz ? Kiedyś ćwiczyłem podobne klimaty z postgresem przy okazji migracji danych z innego systemu. Były dwa względnie wydajne podejścia, związane z paczkowaniem:
1. Bez prepared statementów, sklejanie zapytań. Tworzenie paczki polegało nie tylko na wkładaniu insertów w jedną transakcję, ale także na sklejaniu ich w jeden skrypt, poodzielane średnikami. Zdawało to bardzo dobrze egzamin w przypadku wielu krótkich insertów. W przypadku takich jak mówisz 1-5 KB chyba ma to mniejszy sens, ale spróbować można.
2. Prepared statements+batch insert/update. Nie wiem, jak jest w .NET cie. Ja robiłem w Javie i korzystałem ze sterowników JDBC, które dają taką możliwość (nie jestem tylko pewien, czy sterowniki JDBC to implementują). Jest to połączenie prepared statementa z paczkowaniem samych parametrów. Nie znam wydajniejszej metody jeśli chodzi o metody wysokopoziomowe.
W implementacji wyglada to tak: .... PreparedStatement pstmt = conn.prepareStatement("INSERT INTO employees VALUES(?, ?)");
pstmt.setInt(1, 2000); pstmt.setString(2, "Milo Mumford"); pstmt.addBatch();
pstmt.setInt(1, 3000); pstmt.setString(2, "Sulu Simpson"); pstmt.addBatch();
....
int[] updateCounts = pstmt.executeBatch(); ....
(skopiowane z: http://www.oracle.pwsz.elblag.pl/jav...54/oraperf.htm nie przejmować się 'oracle' w tytule)
Bartek Siebab - 03-04-2006 00:08
> Filip Sielimowicz w dniu 2006-04-02 10:52 pisze:
>> Teoretycznie mogę popaczkować po kilkaset w transakcję. > > W jaki sposób paczkujesz ? > Kiedyś ćwiczyłem podobne klimaty z postgresem przy okazji > migracji danych z innego systemu. Były dwa względnie wydajne podejścia, > związane z paczkowaniem: > > 1. Bez prepared statementów, sklejanie zapytań. Tworzenie paczki > polegało nie tylko na wkładaniu insertów w jedną transakcję, > ale także na sklejaniu ich w jeden skrypt, poodzielane średnikami. > Zdawało to bardzo dobrze egzamin w przypadku wielu krótkich insertów. > W przypadku takich jak mówisz 1-5 KB chyba ma to mniejszy sens, ale > spróbować można.
ze względów konstrukcyjnych tak akurat nie mogę na razie zrobić
> 2. Prepared statements+batch insert/update. > Nie wiem, jak jest w .NET cie. Ja robiłem w Javie i korzystałem > ze sterowników JDBC, które dają taką możliwość (nie jestem tylko > pewien, czy sterowniki JDBC to implementują). > Jest to połączenie prepared statementa z paczkowaniem samych parametrów. > Nie znam wydajniejszej metody jeśli chodzi o metody wysokopoziomowe.
Mam teraz zrobione na prepared właśnie ale po każdym ustawieniu parametrów wykonuję statement, niemniej sprawdzę czy...
> W implementacji wyglada to tak: > ... > PreparedStatement pstmt = > conn.prepareStatement("INSERT INTO employees VALUES(?, ?)"); > > pstmt.setInt(1, 2000); > pstmt.setString(2, "Milo Mumford"); > pstmt.addBatch(); > > pstmt.setInt(1, 3000); > pstmt.setString(2, "Sulu Simpson"); > pstmt.addBatch(); > > ... > > int[] updateCounts = pstmt.executeBatch(); > ...
.... czy w sterowniku npgsql da się jakoś "dodawać" parametry do bacza by później je jedną serią wykonać
-- ..---------- -------- ------ ---- ---- --- - -- - | Bartek `saphire` Siebab http://bartek.siebab.net
Bartek Siebab - 04-04-2006 00:08
> Bartek Siebab w dniu 2006-04-02 19:04 pisze:
>>> Teoretycznie mogę popaczkować po kilkaset w transakcję. >> >> W jaki sposób paczkujesz ? >> Kiedyś ćwiczyłem podobne klimaty z postgresem przy okazji >> migracji danych z innego systemu. Były dwa względnie wydajne podejścia, >> związane z paczkowaniem: >> >> 1. Bez prepared statementów, sklejanie zapytań. Tworzenie paczki >> polegało nie tylko na wkładaniu insertów w jedną transakcję, >> ale także na sklejaniu ich w jeden skrypt, poodzielane średnikami. >> Zdawało to bardzo dobrze egzamin w przypadku wielu krótkich insertów. >> W przypadku takich jak mówisz 1-5 KB chyba ma to mniejszy sens, ale >> spróbować można. > > ze względów konstrukcyjnych tak akurat nie mogę na razie zrobić
Jednak przerobiłem aplikację by szła w prepared _oraz_ z transakcjami paczkowanymi po kilkaset sztuk insertów - postęp w szybkości znaczny, ze średnio 100 insertów/sek teraz leci średnio po *220* insertów/sek
>> 2. Prepared statements+batch insert/update. >> Nie wiem, jak jest w .NET cie. Ja robiłem w Javie i korzystałem >> ze sterowników JDBC, które dają taką możliwość (nie jestem tylko >> pewien, czy sterowniki JDBC to implementują). >> Jest to połączenie prepared statementa z paczkowaniem samych parametrów. >> Nie znam wydajniejszej metody jeśli chodzi o metody wysokopoziomowe. > > Mam teraz zrobione na prepared właśnie ale po każdym ustawieniu > parametrów wykonuję statement, niemniej sprawdzę czy... > >> W implementacji wyglada to tak:
>> pstmt.addBatch(); >> int[] updateCounts = pstmt.executeBatch(); >> ... > > ... czy w sterowniku npgsql da się jakoś "dodawać" parametry > do bacza by później je jedną serią wykonać
Niestaty nie dało się tak zrobić - prepared mam raz ale w transakcji pakując inserty wykorzystujące wcześniej z'prepared'owany insert leci już ponad 2x szybciej. Aktualnie po 500 rekordów w transakcji wydaje się być optymalną wielkością paczki :)
-- ..---------- -------- ------ ---- ---- --- - -- - | Bartek `saphire` Siebab http://bartek.siebab.net
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
=?ISO-8859-2?Q?Narz=EAdzie_do_budowania_zapyta=F1_SQL=2C?==?I SO-8859-2?Q?_PL/PgSQL=2C_PL/SQL=2C_T-SQL?=
[pgsql] Akcja w =?iso-8859-2?b?emFsZb9ub7ZjaQ==?= od liczby zmienionych =?iso-8859-1?q?rekord=F3w?=
[sql][pgsql] zapytanie sql
[pgsql] Wykonanie triggera po =?ISO-8859-2?Q?zako=F1czeniu_tra?==?ISO-8859-2?Q?nsakcji?=
[pgsql] =?ISO-8859-2?Q?Prawid=B3owe_post=EApowanie_w_przyp?==?ISO-8859-2?Q?adku_awarii?=
[PGSQL] Funkcje =?ISO-8859-2?Q?zwracaj=B1ce_=27rowset=27_i_?==?ISO-8859-2?Q?tabele_tymczasowe?=
[pgsql] 7.4 =?ISO-8859-2?Q?og=B3upia=B3_przy_zak=B3adaniu_?==?ISO-8859-2?Q?indeksu?=
[pgsql] Zmiana schematu do =?ISO-8859-2?Q?kt=F3rego_nalezy_o?==?ISO-8859-2?Q?biekt=2E?=
[postgresql] INSERT OR UPDATE - jak =?ISO-8859-2?Q?b=EAdzie_na?==?ISO-8859-2?Q?jlepiej=3F?=
Która z baz: [PGSQL] czy [MySQL] będzie lepsza w takim zastosowaniu (masowe UPDATE)
zanotowane.pldoc.pisz.plpdf.pisz.plchinska-zupka.opx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|