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ń:
//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
Ten post edytował sawic 4.01.2007, 23:12:19