Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Optymalizacja zapytań
Forum PHP.pl > Forum > Przedszkole
torbicki65
Witam
Czy macie jakiś pomysł, na optymalizacje tego zapytania? Generalnie projekt dotyczy naszej klasy (eksportu znajomych - www.znajomi.boo.pl) i ten kawałek skryptu wygląda tak - po pobraniu danych z listy znajomych, wrzuca je w tabele tymczasową i w pętli za każdy kolejny rekord porównuje, czy istnieje już w tabeli docelowej, czy nie (jeśli istnieje, to robi UPDATE, jeśli nie istnieje, to INSERT). Problem w tym, że najczęściej korzystają z tego osoby, które mają dużo znajomych i przy liczbie kilkuset pojawia się problem zasobochłonności.


Kod
$pyt="INSERT INTO tablela_tymczasowa SET id_zn='$id', dane='$imie', miasto='$miasto', profil='$numer'";
   mysql_query($pyt);
      
   // sprawdzanie czy rekordy juz sa - jesli nie, dodaje, jesli tak - aktualizuje
   $pyt=mysql_query("SELECT * FROM $tabela_docelowa WHERE id_zn='$id' AND profil='$numer'");
    
   if(!mysql_fetch_row($pyt))
   {
   $pyt="INSERT INTO $tabelank SET id_zn='$id', dane='$imie', miasto='$miasto', profil='$numer'";
   mysql_query($pyt);
   }
   else
   {
   $staryid=$pyt['id'];
   $pyt="UPDATE $tabelank SET id_zn='$id', dane='$imie', miasto='$miasto', profil='$numer' WHERE id='$staryid'";
   mysql_query($pyt);


i powtarza się ten cykl zapytań dla każdego kontaktu, czyli nawet kilkaset razy (w pętli while).
Domyślam się, że nie jest to optymalne, skoro różne serwery sobie z tym nie radzą (chyba tylko na home.pl było z tym OK).

Generalnie mam jeszcze drugi problem, związany też z MySQL, chodzi o szukanie wspólnych znajomych w dwóch profilach na naszej klasie - tutaj też używam tablicy tymczasowej i wymodziłem takie zapytanie

Kod
$pyt=mysql_query("SELECT * FROM tablica_docelowa WHERE tablica_docelowa.id_zn IN (SELECT tablica_tymczasowa.id_zn FROM tablica_tymczasowa WHERE tablica_tymczasowa.profil='$numer') && tablica_docelowa.profil='$g_numer'");

(przy czym to już idzie normalnie, nie w pętli).
Kilka wyjaśnień odnosnie struktury:
id_zn - jest to numer profilu znajomego na naszej klasie
profil - numer profilu, z którego eksportowane są kontakty
Zyx
Odnośnie pierwszego problemu, polecam zapoznać się ze składnią INSERT .... ON DUPLICATE KEY UPDATE automatycznie wykonującą wszystkie te testy na obecność rekordu, który teraz próbujesz robić ręcznie. Dokładniejszy opis znajdziesz tutaj: http://dev.mysql.com/doc/refman/5.0/en/ins...-duplicate.html
torbicki65
Dzięki, przejrzałem manuala, ale problem jest taki, że pola 'id_zn' i 'profil' nie są (i nie mogą) być unikalne, bo ktoś może być znajomym wielu osób i jednocześnie też mieć wielu znajomych, czyli jedyny warunek, to taki, że wybrana kombinacja obu pól nie może się powtórzyć (np mogą być dane 10|99; 10|50; 12|99; 13|99, ale nie może być 10|99;10|99). Wiem, że nie jest to prawidłowa konstrukcja tabeli, ale generalnie nie chce mi się tego zmieniać teraz, chociaż pewnie będę musiał prędzej czy później.
Myślałem też o REPLACE ale ona też wymaga unikalnego pola.

Odświeżam, może ktoś pomoże, bo ciągle siedzę w tym samym bagnie i nie mam pomysłu.
Rozbiłem tabelę na 2 tabele (bo i tak w końcu kiedyś musiałem, przy aktualnych 80 tys rekordów, ok 10 tysięcy można zaoszczędzić) i teraz wyglądają one w sposób taki:

tabela z danymi
nr profilu (uniq) | dane | miasto

tabela z relacja znajomych
nr profilu | nr profilu znajomego

Więc o ile połowicznie poradziłem sobie z problemem pierwszym i mogę już w jednym zapytaniu MySQL z pomocą "on duplicate key" aktualizować albo dodawać wpis.

Problemem pozostaje jednak druga tabela, gdzie też muszę zaktualizować relacje pomiędzy numerami profili - tutaj nie ma wartości unique, bo może się powtórzyć zarówno pole nr profilu jak i nr profilu znajomego, ale nigdy oba na raz.. więc odpada replace i on duplicate key..

Jakiś pomysł?
Zyx
Ale kombinacja id_zn ORAZ profil jest już chyba unikalna, prawda?
torbicki65
Tak, dlatego mam nadzieję, że nakierujesz mnie, bo naprawdę albo głupieję, albo za dużo o tym myślę... czy da się zrobić dla tej unikalnej kombinacji coś, żeby nie zaprzęgać za dużo php (czyli stara wersja skryptu)..

edit:
OK, nie przypuszczałem, że da się zrobić UNIQUE dla obu pól naraz a nie pojedynczo. Ave!
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.