ďťż
 
[MySQL] Jak =?ISO-8859-2?Q?zoptymalizowa=E6_te_operacje_=3F?= ďťż
 
[MySQL] Jak =?ISO-8859-2?Q?zoptymalizowa=E6_te_operacje_=3F?=
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

[MySQL] Jak =?ISO-8859-2?Q?zoptymalizowa=E6_te_operacje_=3F?=



sawic - 04-01-2007 14:10
[MySQL] Jak =?ISO-8859-2?Q?zoptymalizowa=E6_te_operacje_=3F?=
  Witam.
Podliczam parę rzeczy w bazie, wiem, że robię to w sposób bezsensowny
(ale działa jak należy), ale nie wiem jak to zoptymalizować.
Wklejam żywcem kod, może ktoś się pokusi o przeanalizowanie tego:

//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());

Wszystko, co wcześniej kombinowałem rozłożyło te 'limit 10'.
Muszę mieć 10 ostatnich wyników dla każdego, bez względu kiedy one były.
Może ktoś by doradził coś, bo te obliczenia trwają strasznie długo :(

Pozdrawiam





Rafal \(sxat\) - 04-01-2007 14:10

  > $sql = "create temporary table db.tmpp(user char(20), wynik char(10),
> stawka int(3), profit float) ENGINE = MEMORY";

o ile chyba wiem to tabela temporary nigdzie nie jest zapisywana wiec po co
engine=memory?




sawic - 05-01-2007 00:03

  Rafal (sxat) napisał(a):
> o ile chyba wiem to tabela temporary nigdzie nie jest zapisywana wiec po co
> engine=memory?

Po to właśnie, że nie chcę nic zapisywać.
Tylko wybrać parę rekordów, wykonać na nich obliczenia, obliczenia
zapisać, rekordy skasować.

W uproszczeniu - mam w bazie wiele rekordów, każdy rekord ma date i
użytkownika. Ja chcę wybrać 10 ostatnich dla każdego użytkownika i
wykonać na nich obliczenia. Nie mam zielonego pojęcia jak to sprawniej
wykonać, niż ten bezsens który napisałem powyżej.

Pozdrawiam




zarafiq@poczta.onet.pl - 05-01-2007 00:04

  > W uproszczeniu - mam w bazie wiele rekordów, każdy rekord ma date i
> użytkownika. Ja chcę wybrać 10 ostatnich dla każdego użytkownika i
> wykonać na nich obliczenia. Nie mam zielonego pojęcia jak to sprawniej
> wykonać, niż ten bezsens który napisałem powyżej.

Nie napisałeś jaka baza, jeśli Twoja wersja ma "stored procedures" to
już samo przeniesienie tego na serwer powinno troche pomóc.

Pozdrawiam
zarafiq

--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl





sawic - 05-01-2007 00:04

  zarafiq@poczta.onet.pl napisał(a):
>> W uproszczeniu - mam w bazie wiele rekordów, każdy rekord ma date i
>> użytkownika. Ja chcę wybrać 10 ostatnich dla każdego użytkownika i
>> wykonać na nich obliczenia. Nie mam zielonego pojęcia jak to sprawniej
>> wykonać, niż ten bezsens który napisałem powyżej.
>
> Nie napisałeś jaka baza, jeśli Twoja wersja ma "stored procedures" to
> już samo przeniesienie tego na serwer powinno troche pomóc.

MySQL
# Wersja serwera: 5.0.26-log
# Wersja protokołu: 10
Typ tabel: MyISAM

strored procedure wg manuala jest.

Jak to ugryźć ?

Pozdrawiam




Artur Muszynski - 05-01-2007 00:04
=?iso-8859-2?Q?Re:_=5BMySQL=5D_Jak_zoptymalizowa=E6_te_operac je_=3F?=
  sawic wrote:
> Witam.
> Podliczam parę rzeczy w bazie, wiem, że robię to w sposób bezsensowny
> (ale działa jak należy), ale nie wiem jak to zoptymalizować.
> Wklejam żywcem kod, może ktoś się pokusi o przeanalizowanie tego:

[...]
ile jest tych userów? Tzn ile razy wykona zapytanie w pętli. Jeśli bardzo
dużo, to może tak: Wybierz ostatni rekord (z pomocą agregacji MAX) dla
wszystkich userów i zapisz do temp. Potem wybierz wcześniejszy i tak 10 razy
(lepsza taka pętla niż 100 czy 1000). Żeby wybrać wcześniejszy trzeba by
wykluczyć z wyników, te już wcześniej wybrane, na przykład robić złączenie
statystyki z tabelą tymczasową. Nie mam czasu, żeby się bardziej w to
wgłębiać, ale może uzyskasz dzięki temu inne spojrzenie na problem. Z typem
memory nie musisz aż tak kombinować, przecież i tak tabela tymczasowa
zostanie usunięta po zamknięciu połączenia.

artur




sawic - 05-01-2007 00:04

  Artur Muszynski napisał(a):
> ile jest tych userów? Tzn ile razy wykona zapytanie w pętli. Jeśli
> bardzo dużo, to może tak: Wybierz ostatni rekord (z pomocą agregacji
> MAX) dla wszystkich userów i zapisz do temp. Potem wybierz wcześniejszy
> i tak 10 razy (lepsza taka pętla niż 100 czy 1000). Żeby wybrać
> wcześniejszy trzeba by wykluczyć z wyników, te już wcześniej wybrane, na
> przykład robić złączenie statystyki z tabelą tymczasową. Nie mam czasu,
> żeby się bardziej w to wgłębiać, ale może uzyskasz dzięki temu inne
> spojrzenie na problem. Z typem memory nie musisz aż tak kombinować,
> przecież i tak tabela tymczasowa zostanie usunięta po zamknięciu
> połączenia.

No pokombinuję.
Userów jest około 500 a całość wykonuje się jakieś 5 sek. To dużo za
dużo. Najwięcej czasu tracę na pętle while i połączenia do bazy.
Chciałbym znaleźć rozwiązanie, żeby jak najwięcej operacji wykonać na
bazie danych a jak najmniej na php.

Pozdrawiam
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    Gdzie MySQL 4.1, a gdzie 5.0? [MS SQL] "set names" (mySQL) w MS SQL oracle -> oracle lub oracle -> mysql replikacja - programy [mysql 4.0] SELECT t1.id, t1.foo FROM t1 oraz COUNT t2 w jednym zapytaniu. [MySQL] Zwrot tego, co pasuje i nie pasuje :-/ [pgsql] Dostosowanie składni MySQL 5.0 -> PGSQL 8.1 [mysql] galeria zdjec - numerowanie zdjec [MySQL] Zapytanie z pliku , wynik do pliku [mysql] CONCAT agregujący, ale nie GROUP_CONCAT() mysql data 0000-00-00 na koniec
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • red-hacjenda.opx.pl
  • Cytat

    Decede mihi sole - nie zasłaniaj mi słonca.
    Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści
    Hoc fac - tak czyń.
    A tergo - od tyłu; z tyłu.
    I czarne włosy posiwieją. Safona

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com