ďťż
 
Jaka strategia dla update'u kilkudziesięciu milionów rekordów wmysql'u? ďťż
 
Jaka strategia dla update'u kilkudziesięciu milionów rekordów wmysql'u?
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

Jaka strategia dla update'u kilkudziesięciu milionów rekordów wmysql'u?



tomjan@jay.au.poznan.pl - 13-11-2006 00:45
Jaka strategia dla update'u kilkudziesięciu milionów rekordów wmysql'u?
  Witam grupowiczów

Ponieważ nie moge znaleźć gotowej recepty w żadnej z książek + w archiwum grupy
+ w googlach zdecydowałem się wkońcu napisać na grupę.

Załużmy że nasza przykładowa baza wygląda jak baza rodowod (patrz koniec tej
wiadomości) w której znajduje się od kilku do kilkudziesięciu milionów rekordów.
pola osobnik,ojciec,matka,data_ur są uzupełniane a następnie program w C/C++
pobiera te informacje i na ich podstawie oblicza wartości 'f' oraz 'c' dla
każdego osobnika.

Pytanie brzmi
Jaka jest strategia wprowadzenia dla tych milionów rekordów obliczonej wartości
'f' oraz 'c'???

Czy robić to z poziomu aplikacji? jeśli tak to jak? czy ktoś mógłby podać
przykładowy kod na to. jak to zaimplementować w C + jak to supportować
konfiguracją mysql'a?

A może zrzucać to do pliku tekstowego jako liste query'ow i wciągać przez
mysqlowego klienta?

a może robiąc jakąś sztuczke 'insert' do jakiejś tymczasowej tabeli powiązanej
referencja zamiast 'update'?

Ja prubóje robić to z poziomu aplikacji w następujący sposób :

Rodowod::iterator it;
for (it=begin();it!=end();it++){
sprintf(query, "update rodowod set f=%f,c=%f where id
='%s'",(*this)[it->first]->f,(*this)[it->first]->c,(*this)[it->first]->id_str.c_str());

if(mysql_query(mysql,query)){
printf("%d ", mysql_errno(mysql));
}
}

powiem szczerze że idzie to masakrycznie wolno, zaimplementowałem wskaźnik
postępu i widze że co kilka tys. rekordów procedura update'u stoi w miejscu od
minuty do kilku minut. Prawde mówiąc nie wiem jak wyśledzić co się dzieje w tym
czasie. zwiększyłem w pliku my.cfg wartość dla zmiennej key_buffer do 3072M i nic

wyczytałem w archiwum formu + w googlach że najlepiej opóźnić wykonanie wielu
zapytań i wykonywać je naraz w większych "paczkach".
ładnie brzmi ale jak to zaimplementować ? na poziomie API C czy na poziomie
SQL'a. nie moge znaleźć na to gotowca.

dziękuję za jakiekolwiek podpowiedzi, sugestie, linki.

tomasz

ps. zapomniałbym o danych technicznych: Debian + mysql-5.0.24a-Debian_9 + 64bit
+ 8G RAM + 2x AMD Opteron(tm) 2592.316MHz

CREATE TABLE rodowod(
id int(11) UNSIGNED NOT NULL auto_increment,
osobnik varchar(25) NOT NULL default '',
ojciec varchar(25) NOT NULL default '',
matka varchar(25) NOT NULL default '',
f real,
c real,
data_ur DATE,
PRIMARY KEY (id),
INDEX (osobnik),
INDEX (data_ur)
)ENGINE=MyISAM;

--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl





zarafiq@poczta.onet.pl - 13-11-2006 00:45

  > Witam grupowiczów
>
> Ponieważ nie moge znaleźć gotowej recepty w żadnej z książek + w
> archiwum grupy + w googlach zdecydowałem się wkońcu napisać na grupę.

MySQL'a znam dość powierzchownie, ale...
Wersja 5 obsługuje już zdaje się STORED PROCEDURES, czy nie da się
tego policzyć tam? Uniknąłbyś pompowania tych milionów rekordów
do aplikacji, a następnie milionów updateów z aplikacji.

Pozdrawiam
zarafiq

--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl




tomjan@jay.au.poznan.pl - 13-11-2006 00:46

  > MySQL'a znam dość powierzchownie, ale...
> Wersja 5 obsługuje już zdaje się STORED PROCEDURES, czy nie da się
> tego policzyć tam? Uniknąłbyś pompowania tych milionów rekordów
> do aplikacji, a następnie milionów updateów z aplikacji.

kod aplikacji w C++ zamyka się w 1000 lini kodu. więc niby niewiele.
ale jak to kod C++ wykorzystuje STL,szablony i parę algorytmicznych trików +
rachunek macierzowy. więc te 1000 lini naprawde dużo robi.

pewnie dałoby radę ale... wole posłuchać o innych możliwych rozwiązaniach.

(Choćby zwykła rekurencja już jest trudna do zaimplementowania w postaci
mysqlowej funkcji użytkwnika.)

dziękuję za odpowiedź

tomasz

--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl




tomjan@jay.au.poznan.pl - 13-11-2006 00:46

  > pewnie dałoby radę ale... wole posłuchać o innych możliwych rozwiązaniach.

ponieważ nikt z forum nie kwapi się do hardcore'owej odpowiedzi jestem zmuszony
sam mozolnie przedzierać się przezten problem (I żeby nikt nie myślał że mam
jakieś pretensje, wiem że taki 'lajf').

Zmieniłem implementacje z:

Rodowod::iterator it;
for (it=begin();it!=end();it++){
sprintf(query, "update rodowod set f=%f,c=%f where id
='%s'",(*this)[it->first]->f,(*this)[it->first]->c,(*this)[it->first]->id_str.c_str());
mysql_query(mysql,query);
}

na podaną w przykładzie
http://dev.mysql.com/doc/refman/5.0/...-handling.html
czyli w pseudokodzie:

mysql_stmt_init()
mysql_stmt_prepare()
/* set up input buffers for all 3 parameters */
bind[0].buffer_type= MYSQL_TYPE_DATE;
mysql_stmt_bind_param()
Rodowod::iterator it;
for (it=begin();it!=end();it++){
mysql_stmt_execute()
}

pomogło:
czas update'u 7 milionów rekordów spadł ze 150 min do 120.

czy ktoś mógłby się wypowiedzieć czy to jest względnie dobry czas dla takiego
zadania czy mam jeszcze szukać innych możliwości optymalizacji?
może ktoś podobnie duże zadanie robi np. w pół godziny?
jeśli tak to jak?

acha, procesor:
model name : AMD Opteron(tm) Processor 252
stepping : 1
cpu MHz : 2592.316
cache size : 1024 KB

versja bazy:
5.0.24a-Debian_9

dziękuję za odpowiedź

tomasz

--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl





zarafiq@poczta.onet.pl - 13-11-2006 00:46

 
> for (it=begin();it!=end();it++){
> mysql_stmt_execute()
> }

Rozumiem że nie masz *dokładnie* tak.

> pomogło:
> czas update'u 7 milionów rekordów spadł ze 150 min do 120.

Wychodzi blisko 1000 na sekundę. Niby nieźle ale czy można lepiej?
Za mało mam danych żeby powiedzieć. Mógłbyś napisać procedurę,
która aktualizuje parę tysięcy rekordów i sprawdzić ile jej to
zajmuje - to mógłby być punkt odniesiena.

Pozdrawiam
zarafiq

--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    [ms sql] =?ISO-8859-2?Q?wy=B6wietlenie_pierwszych_5_rekord?==?ISO-8859-2?Q?=F3w_z_zapytania_=3F_odpowiednik_ROWNUM_w_o?== ?ISO-8859-2?Q?raclu_dla_MS_SQL=27a?= [MySQL] =?ISO-8859-2?Q?Wy=B6wietlenie_kolejnej_pozycji=2C_?==?ISO-8859-2?Q?jak=B1_mia=B3by_dany_rekord=2C_gdybym_czyta=B3 _?==?ISO-8859-2?Q?wg_konkretnych_kryteri=F3w=2E_Da_si=EA_=3F?= Jak =?ISO-8859-2?Q?zamieni=E6_dwa_pola_jednej_kolumny_?==?ISO-8859-2?Q?w_dw=F3ch_rekordach_za_pomoc=B1_jednego_zapyt? ==?ISO-8859-2?Q?ania=3F?= [mysql/php] jak =?ISO-8859-2?Q?zliczy=E6_ilo=B6=E6_unikalnyc?==?ISO-8859-2?Q?h_rekord=F3w_w_jednym_zapytaniu=3F?= =?ISO-8859-2?Q?WY=B6wietlenie_rekord=F3w_pocz=B1wszy_od_?==?I SO-8859-2?Q?danej_litery=2E=2E=2E?= =?iso-8859-2?Q?=5BMySQL=5D_Wy=B6wietlenie_wszystkich_rekordow _zawierajacy?==?iso-8859-2?Q?ch_duplikat_a__moze_inna_struktura_bazy_danych ?= [pgsql] Akcja w =?iso-8859-2?b?emFsZb9ub7ZjaQ==?= od liczby zmienionych =?iso-8859-1?q?rekord=F3w?= [postgresql] kilka =?ISO-8859-2?Q?rekord=F3w_subquery_jako_?==?ISO-8859-2?Q?string?= [mysql] Wyszukanie =?ISO-8859-2?Q?rekord=F3w=28powiazane_tabel?==?ISO-8859-2?Q?e=29?= [MySQL]: Dodanie zliczania =?ISO-8859-2?Q?rekord=F3w_do_rozb?==?ISO-8859-2?Q?udowanego_zapytania?=
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • nawschodzie.xlx.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

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com