Baza to mysql 5+
Zapytanie działa, ale jest strasznie niewydajne.
W uproszczeniu zmagam się z takim problemem:
Tabela 10k rekordów, 500 unikalnych użytkowników. W każdym rekordzie mam datę, użytkownika, i jakieś tam dane.
Muszę wykonać obliczenia dla 10-ciu ostatnich rekordów (sortując po dacie desc) dla każdego użytkownika.
Narazie załatwiam to w ten sposób, że czytam unikalnych użytkowników, następnie dla każdego czytam 10 ostatnich wartości konkretnych pól, wpisuję to do tymczasowej tablicy, kolejno wykonuję obliczenia dla każdego użytkownika i dopiero wtedy otrzymane wyniki wpisuję do właściwej tablicy.
Jest to strasznie bez sensu.
Aby urzeczywistnić to co powyżej napisałem, wklejam żywcem kod, obrazujący mój sposób dokonywania obliczeń:
//stworz tymczasowa tablice $sql = "create temporary table db.tmpp(user char(20), wynik char(10), stawka int(3), profit float) ENGINE = MEMORY"; $result = mysql_query($sql) OR die(mysql_error()); //zczytaj uzytkownikow (sa tylko unikalni, bo juz wczesniej robilem GROUP BY) $sql = "select user from db.statystyki where nowy = '1'"; $result = mysql_query($sql) OR die(mysql_error()); //dla kazdego zczytaj 10 ostatnich wynikow i wpisz TO do tabeli tymczasowej while ($line = mysql_fetch_array ($result)) { $sql2 = "insert into db.tmpp(user, wynik, stawka, profit) select user, wynik, stawka, profit from db.kupon where user = '". $line['user'] ."' and (koniec = '1' or (koniec = '0' and wynik = 'przegrany')) and data_dodania is not null order by data_wynik desc, data_dodania desc limit 10"; $result2 = mysql_query($sql2) OR die(mysql_error()); } //dla kazdego uzytkownika podlicz jego 10 ostatnich wynikow $sql = "select round(((sum(profit) / sum(stawka)) * 100),0) as zysk, count(case when wynik = 'wygrany' then 1 else null end) as wygranych, count(case when wynik = 'zwrot' then 1 else null end) as zwrotow, count(case when wynik = 'przegrany' then 1 else null end) as przegranych, user from db.tmpp group by user"; $result = mysql_query($sql) OR die(mysql_error()); //zapisz do glownej tabeli obliczone dane while ($line = mysql_fetch_array ($result)) { $sql2 = "update db.statystyki set zysk10 = '". $line['zysk'] ."', trafionych = '". $line['wygranych'] ."', zwrotow = '". $line['zwrotow'] ."', nietrafionych = '". $line['przegranych'] ."' where nowy = '1' and user = '". $line['user'] ."' limit 1"; $result2 = mysql_query($sql2) OR die(mysql_error()); } //skasuj tymczasowa tablice $sql = "drop table db.tmpp"; $result = mysql_query($sql) OR die(mysql_error());
Zajmuje to czasem nawet do 5 sek. Za dużo.
Chciałbym jak najwięcej obliczeń przerzucic na bazę, i jednocześnie zminimalizować ilość odpytań.
Jak się do tego zabrać ?
Pozdrawiam