Witam.
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ń:
  1. //stworz tymczasowa tablice
  2. $sql = "create temporary table db.tmpp(user char(20), wynik char(10), stawka int(3), profit float) ENGINE = MEMORY";
  3. $result = mysql_query($sql) OR die(mysql_error());
  4. //zczytaj uzytkownikow (sa tylko unikalni, bo juz wczesniej robilem GROUP BY)
  5. $sql = "select user from db.statystyki where nowy = '1'";
  6. $result = mysql_query($sql) OR die(mysql_error());
  7. //dla kazdego zczytaj 10 ostatnich wynikow i wpisz TO do tabeli tymczasowej
  8. while ($line = mysql_fetch_array ($result))
  9. {
  10. $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";
  11. $result2 = mysql_query($sql2) OR die(mysql_error());
  12. }
  13. //dla kazdego uzytkownika podlicz jego 10 ostatnich wynikow
  14. $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";
  15. $result = mysql_query($sql) OR die(mysql_error());
  16. //zapisz do glownej tabeli obliczone dane
  17. while ($line = mysql_fetch_array ($result))
  18. {
  19. $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";
  20. $result2 = mysql_query($sql2) OR die(mysql_error());
  21. }
  22. //skasuj tymczasowa tablice
  23. $sql = "drop table db.tmpp";
  24. $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