Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem z przeliczaniem duzej ilości wierszy[PHP+SQL]
Forum PHP.pl > Forum > PHP
adrian512
Witam wszystkich,

mam problem z przeliczeniem duzej ilosci wierszy w bazie danych a dokladniej w tabeli : DokFin mam 50tys wierszy, Historiafin mam 60tys wierszy, Towary okolo 6 tys wierszy.


potrzebuje program który pobierze mi w zaleznosci od dat ID dokumentu finansowego z DokFin, pozniej wyszuka to ID w tabeli HistoriaFin, następnie pobierze z HistoriaFin IDtowaru,cene zakupu i ilosc( cena i ilosc pomnoży i zapisze do zmiennej) a Id towaru wyszuka w tabeli Towary i pobierz idGrupy do której nalezy towar.

Napisałem cos takiego :

  1. $query = "select Id from DokFin where (DokFin.DataSprzedazy between '2014-06-01' and '2014-06-02') ";
  2.  
  3. $wynik = mysql_query($query);
  4. while ($rekord = mysql_fetch_array($wynik)) {
  5.  
  6. $tempiddok[]=$rekord['Id']; //pobieram Id dokumentu sprzedazy spelniajace zakres dat
  7. }
  8.  
  9. foreach ($tempiddok as $key => $val) {
  10. $query2 = "select IdTowaru, Ilosc, ce_zn from HistoriaFin where HistoriaFin.IdDokFin like '$val' "; //pobieram id towaru spelniajacego zakres dat
  11. $wynik2 = mysql_query($query2);
  12. while ($rekord2 = mysql_fetch_array($wynik2)) {
  13. $tempidtowaru[]=$rekord2['IdTowaru'];
  14.  
  15. // Sprawdzam do jakiej grupy nalezy towar///
  16.  
  17. //licze wartosc danego dokumentu magazynowego
  18. $wartosczakupu=$rekord2['Ilosc']*$rekord2['ce_zn'];
  19. $wartoscgrupy[$tempidgrupy]=$wartoscgrupy[$tempidgrupy]+$wartosczakupu;
  20. }


Problem w tym gdy daty są np odlegle o 3 miesiace to program wykonuje to dłuzej niz 8000sekund.. Ktoś pomoże jak to rozwiazac?
nospor
1) Do porownania konkretnej wartosci nie uzywa sie LIKE tylko =
2) To co tu wszystko masz, realizuje się jednym zapytaniem a nie petryliardem w petli jak masz teraz. Poczytaj o JOINach w mysql
Turson
  1. SELECT DokFin.id, HistoriaFin.cena, HistoriaFin.ilosc, Towary.idGrupy
  2. FROM DokFin JOIN HistoriaFin ON DokFin.id = HistoriaFin.id
  3. JOIN Towary ON Towary.id = DokFin.id
  4. WHERE HistoriaFin.IdDokFin = DokFin.id AND (DokFin.DataSprzedazy BETWEEN '2014-06-01' AND '2014-06-02')
nospor
@Turson, zapomniales o czyms....
HistoriaFin.IdDokFin = $val
wink.gif
Turson
Podejrzewam, że IdDokFin jest integerem
nospor
A co ma piernik do wiatraka? Chodzi o to, ze zamiast $val ma byc nazwa kolumny z drugiego łączenia...
Turson
Aaa, myślałem że chodzi o brak '', a $val to jakaś zmienna z $_POST czy coś smile.gif
Autor niech sam poprawi
nospor
Nie, nie jest tozmienna z post...z kodu widac wyraznie, ze jest to zmienna z petli po idkach.... a poto przeciez zrobiles złączenie by tej petli nie bylo, nieprawdaz?
Turson
Cytat
myślałem że chodzi o brak '', a $val to jakaś zmienna z $_POST czy coś

Może niejasno, ale napisałem, że myslałem iż $val to zmienna niepochodząca z zapytań, nieprawdaż? biggrin.gif
nospor
Dlatego wyprowadzilem Cię z błędu, nieprawdaż?
Turson
Tak, ale dwukrotnie. W poście #7 napisałem, że już wiem co to jest $val, ale źle zrozumiałeś i w poście #8 wytłumaczyłeś jeszcze raz, więc nie zrozumiałeś kontekstui mojej wypowiedzi.
Ale my mamy problemy smile.gif
nospor
smile.gif
Nie mniej jednak mogles poprawić juz to zapytanie, skoro wiedzialec co jest czym. Autor nie koniecznie musi wiedziec co chciales tym zapytaniem osiągnąć i skoro juz mu dales gotowca, to moglby on byc poprawny.
adrian512
Dzięki bardzo za odpowiedź.

Próbuje na wszystkie sposoby mam coś takiego :

  1. $query = "SELECT DokFin.Id, HistoriaFin.ce_zn, HistoriaFin.Ilosc, Towary.IdGrupy
  2. FROM DokFin JOIN HistoriaFin ON DokFin.Id = HistoriaFin.Id
  3. JOIN Towary ON Towary.Id = DokFin.IdTowaru
  4. WHERE HistoriaFin.IdDokFin = DokFin.Id AND (DokFin.DataSprzedazy BETWEEN '2014-06-01' AND '2014-06-02') " ;
  5.  
  6.  
  7. $wynik = mysql_query($query);
  8. while ($rekord = mysql_fetch_array($wynik)) ....

I dostaje błąd:

Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in ( wskazuje na linijke: while ($rekord = mysql_fetch_array($wynik)) )
Turson
  1. $wynik = mysql_query($query) or die(mysql_error());
adrian512
Dzięki, problem był z złą nazwą tabeli

Ale dalej długo to trwa, jest mozliwosc jeszcze jakoś to poprawić?
nospor
WHERE (DokFin.DataSprzedazy BETWEEN '2014-06-01' AND '2014-06-02') " ;
No i przydalby sie index na pole DataSprzedazy
adrian512
Zrobiłem wszystko jak pisałeś , jednak ten czas dalej taki sam.. (Historiamag zawiera 600tys wierszy,) macie jakieś jeszcze pomysly?
nospor
Przy prawidlowym indeksie nie powinno byc takich problemow.

Pokaz jak wygląda akualne zapytanie oraz pokaz EXPLAIN z tego zapytania
adrian512
Nie wiem czy dobrze użyłem EXPLAIN(wstawiłem zamiast SELECT?)

Podaje kod jak wygląda:
  1.  
  2. $query = "EXPLAIN DokFin.Id, HistoriaFin.ce_zn, HistoriaFin.Ilosc, Towary.IdGrupy
  3. FROM DokFin JOIN HistoriaFin ON DokFin.Id = HistoriaFin.IdDokFin
  4. JOIN Towary ON Towary.Id = HistoriaFin.IdTowaru
  5. WHERE (DokFin.DataSprzedazy BETWEEN '2014-06-01' AND '2014-06-02') " ;
  6.  
  7.  
  8. $wynik = mysql_query($query) or die(mysql_error());
  9. while ($rekord = mysql_fetch_array($wynik)) {
  10.  
  11.  
  12.  
  13.  
  14.  
  15. $tempidgrupy=$rekord['IdGrupy'];
  16.  
  17. $wartosczakupu=$rekord['Ilosc']*$rekord['ce_zn'];
  18. $wartoscgrupy[$tempidgrupy]=$wartoscgrupy[$tempidgrupy]+$wartosczakupu;
  19.  
  20. }



oraz wynik EXPLAIN : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' HistoriaFin.ce_zn, HistoriaFin.Ilosc, Towary.IdGrupy FROM DokFin JOIN Histor' at line 1

Lub z PHPmyAdmin : Explain:
id, select_type, table,type,possible_keys,key,key_len,ref,rows ,Extra
1,SIMPLE,DokFin,range,DataSprzedazy,DataSprzedazy,3,NULL,1053,Using where
1,SIMPLE,Towary,ALL,NULL,NULL,NULL,NULL,9214,,Using join buffer
1,SIMPLE,HistoriaFin,ALL,NULL,NULL,NULL,NULL,547551,Using where; Using join buffer


Masz pomysl?
Turson
Nie zamiast select a przed
adrian512
jak dodam przed, to nic sie nie wykonuje.

Zrobiłęm do przez phpmyadmin to otrzymałem cos takiego :Zdjecie
Turson
Masz klucze podstawowe założone na id danej tabeli?
Możesz nałożyć indeksy jeszcze na kolumnach łączących tabele. Sprawdzaj zapytanie w phpmyadmin, porównuj czas przed i po nałożeniu indeksu.
adrian512
pojawił mi się jeszcze taki bląd: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 4
Turson
A zapytanie?
adrian512
  1. $query = "(SELECT DokFin.Id, HistoriaFin.ce_zn, HistoriaFin.Ilosc, Towary.IdGrupy
  2. FROM DokFin JOIN HistoriaFin ON DokFin.Id = HistoriaFin.IdDokFin
  3. JOIN Towary ON Towary.Id = HistoriaFin.IdTowaru
  4. WHERE (DokFin.DataSprzedazy BETWEEN '2014-06-01' AND '2014-06-02')" ;
Turson
Policz ile razy otworzyłeś nawias a ile zamknąłeś
adrian512
Dzięki bardzo, problem był z Indeksami w bazie sql.

Teraz chodzi szybko wink.gif
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.