Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Prośba o optymalizację zapytania - Update 3200 rekordów
Forum PHP.pl > Forum > Przedszkole
jaro74
Czy możecie mi pomóc w optymalizacji UPDATE dla 3200 rekordów

Teraz jest tragedia. Trwa to ponad 20 min. Prawdopodobnie zamiast pętli PHP while można to zrobić innaczej.

Cytat
<?php
$dbhost1 = "";
$dbuser1 = "";
$dbpassword1 = "";
$db2 = "baza";
$connection1 = mysql_connect($dbhost1,$dbuser1,$dbpassword1) or die (mysql_error());

mysql_select_db($db2,$connection1);

$sql = "SELECT * from jos_comprofiler,tablica22 where jos_comprofiler.cb_001 = tablica22.001";
$results = mysql_query($sql);
while($rek = mysql_fetch_array($results)){


$tb055 = $rek['055'];
$tb001 = $rek['001'];
$cb001 = $rek['cb_001'];
$cb055 = $rek['cb_055'];

mysql_query("UPDATE jos_comprofiler,tablica22 SET jos_comprofiler.cb_055 = '$tb055' WHERE jos_comprofiler.cb_001 = '$tb001'")or die("<br> jos_users not updated. Error is: " . mysql_error());

print $cb001. ' <br>' ;
print $cb055. ' <br>' ;



}
?>
Noidea
Spróbuj takie zapytanie (ale nie w pętli, SELECT niepotrzebny):
  1. UPDATE jos_comprofiler, tablica22 SET jos_comprofiler.cb_055 = tablica22.055 WHERE jos_comprofiler.cb_001 = tablica22.001


Pisane z palca i nie wiem czy dobrze zrozumiałem, co chcesz osiągnąć. Struktura tabel, zaprojektowana przez jakiegoś eksperta baz danych też nie pomaga w zrozumieniu problemu.

zordon
jeśli zmieniasz tylko jedną kolumnę i masz duże prawdopodobieństwo , że się wstawiane wartości mogą powtarzać to możesz stworzyć sobie tablicę pomocniczą:
Kluczami takiej tablicy byłyby wartości które zamierzasz wstawiać do bazy, jako wartość byłaby tablica idków rekordów, które mają tą wartość otrzymać.
Później otrzymaną tablicę przejechałbyś jeszcze jedną pętlą robiąc zapytania update:
  1. UPDATE tab SET col = wartosc_czyli_klucz_tablicy WHERE id_rekorow IN (id_czyli_wartosc_tablicy_1, id_czyli_wartosc_tablicy_2, id_czyli_wartosc_tablicy_3)


czy będzie szybciej - trudno powiedzieć, wszystko zależy od bazy. Powinieneś mieć mniej zapytań do bazy, które są najwolniejsze - testuj smile.gif
jaro74
Moze wytlumacze o co mi chodzi dokladne

po poludniu mam wjazd nowych danych do tablica22

a w nocy musze nimi zaktualizowac dane w jos_comprofiler

pól do aktualizacji jest ok 40 wiekszosc to kwoty


bardzo tego potrzebuje - teraz mi to trwa juz ponad pol godziny

NNOIDEA nie bardzo rozumiem ' SELECT niepotrzebny '

czy mozesz mi sprobowac poprawic ten moj kod please
zordon
Poczytaj o uruchamianiu skryptów php z linii poleceń (CLI)
ixpack
Hmmm ale jeżeli update'ujesz tylko 40 "cen" czy co to tam masz do update'a a znasz klucze...
To nie łatwiej zrobić to tak:
  1. INSERT INTO xxx.yyy (aaa, bbb, ccc) VALUES (:aaa, :bbb, :ccc) ON DUPLICATE KEY UPDATE aaa = VALUES (aaa), bbb = VALUES (bbb), ccc = CALUES (ccc);


Oczywiście ww. zapytanie jest gotowe dla PDO - polecam, bo jest wydajniejszy i bezpieczniejszy.

Co dalej? Bindujesz, pętlujesz dane, które chcesz włożyć/updatenąć i dajesz execute();

Tu masz MEGA łatwy tutorial do PDO TUTEK
jaro74
no nie wiem co jest

sam INSERT trwa kilka sekund a juz z ON DUPLICATE KEY UPDATE zawiecha a aktualizuje tylko jedna tabele w bazie
Cytat
ysql_query("INSERT INTO $db2.jos_comprofiler (id,user_id,firstname,lastname,cb_000,cb_001,cb_002,cb_003,cb_004,cb_005,cb_006,
cb_007,cb_008,cb_009,cb_010,cb_011,cb_012,cb_013,cb_050,cb_051,cb_052,cb_053,cb_0
54,cb_055,cb_056,cb_057,cb_070,cb_071,cb_072,cb_073,cb_074,cb_075,cb_076,cb_077,c
b_090,cb_091,cb_092,cb_093,cb_094,cb_095,cb_096,cb_097,cb_120,cb_130,cb_200,cb_id
wlasciciel)
VALUES ('$new_id','$new_id','$p050','$p051','$p000','$p001','$p002','$p003','$p004','$p005','$p006','$p007','$p008','$p009','$p010','$p011','$p012','$p013','$p050','$p051','$p052','$p053','$p054','$p055','$p056','$p057','$p070','$p071','$p072','$p073','$p074','$p075','$p076','$p077','$p090','$p091','$p092','$p093','$p094','$p095','$p096','$p097','$p120','<pre>$p130</pre>','$p200','$p002') ON DUPLICATE KEY UPDATE cb_055=VALUES('$p055')")
or die("<br> jos_comprofiler not updated. Error is: " . mysql_error());



wiiir
  1. UPDATE jos_comprofiler,tablica22 SET jos_comprofiler.cb_055 = '$tb055' WHERE jos_comprofiler.cb_001 = '$tb001


po co ci tu tabela "tablica22" questionmark.gifquestionmark.gif wogole jej tu nie wykorzystujesz
jaro74
no nie


'$tb055' = $rek[055];

jest wartoscia z 'tablic22' pole '055'






erix
Zacznijmy od tego, czy masz w tej tabeli jakieś indeksy? Jaki to silnik?
ixpack
Nie jestem expertem wink.gif ale taka mala myśl mnie naszła - nie możesz "podzielić" tej giga tabeli? Jeżeli wiesz, że będziesz update robił dla danej kolumny co noc - to wydziel to do osobnej tabeli. Fakt, wszystkie zapytania trzeba będzie przerobić - ale to chyba jest jak z malowaniem... Jak najpierw przygotujesz grunt to malowanie jest proste, a jak olejesz grunt to farbę trzeba kłaść 4 razy.
I jak @Erix napisał - indeksy, typy danych, to czcy się rekordy lubią powtarzać itp. - to wszystko i więcej wpływa na wydajność.

Np. W jednej z kolumn mam cenę we floacie, ale mniej pamięci będzie często zajmował zwykły integer... A wystarczy wyciągane dane przeformatować.
Jeżeli dane się powtarzają - to tabela jest źle zorganizowana (nie mówię tu o imieniu np. - ale równierz to wyciągnął bym do innych tabel).
Przykładowy text: Bla bla bla - to może być char albo varchar albo text - chyba znasz różnice? I to ile zajmują miejsca? W dużych bazach wszystko ma znaczenie...
Jedno z fajnych imo rozwiązań to nadawanie id pewnym wartościom np. w bazie powtarza się "nazwa a, nazwa b ... nazwa z" - aby nadać id potrzebujemy 32 liczb, a same nazwy zajmować będą więcej pamięci. Dlatego lepiej imo dać w tabeli id do tej nazwy niż całą nazwę - a zazwy w osobnej tabeli.
To czy silnik jest InnoDB czy inny - też ma znaczenie. To gdzie srver się znajduje też. To jak server jest skonfigurowany też.
jaro74
Dzieki za info , jest rozwiazanie.

Jak pisalem wczesniej INSERT dziala kilka sekund

Przerobilem INSERT tak jak podpowiedzial ixpack i teraz update za pomoca ON DUPLICATE KEY UPDATE dziala moment i na dodatek dodaje nowych userow jak pojawia sie tablica22
a sprawdzilem za pomoca samego update i muli (cos to UPDATE w mysql nie jest do konca OK )

Cytat
ON DUPLICATE KEY UPDATE
cb_003='$p003',
cb_004='$p004' itd


Silnik jest na MyISAM i z tego wyczytalem na InnDB by jeszcze szybciej dzialalo.

System bedzie sie rozwijal i na pewno tu jeszcze wroce smile.gif . Dzieki za pomoc.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.