![]() |
![]() |
![]()
Post
#1
|
|
![]() Grupa: Zarząd Postów: 3 503 Pomógł: 28 Dołączył: 17.10.2002 Skąd: Wrocław ![]() |
Witam. To moj pierwszy post na forum. W sumie mógłbym go nawet nie pisać, ale lepiej nie mieć zerowego konta (podobno zerówki będą kasowane
![]() W czym rzecz: Tworzę stronę dla pewnej ligi piłkarskiej (http://www.alpn.prv.pl - jakby ktoś był ciekawy). I przyszło do stworzenia tabeli fer-play. Czyli zliczyc zolte i czerwone kartki kazdego zawodnika, pogrupowac ich wedlug druzyn, i obliczyc punkty dla kazdej druzyny. Mam dwie tabele, jak stoi ponizej. Kod CREATE TABLE alpn_druzyny (
id_teamu int(10) unsigned NOT NULL auto_increment, nazwa varchar(255) NOT NULL default '', rozegrane int(11) NOT NULL default '0', liga set('I','II') NOT NULL default '', bramki_strzelone int(10) unsigned NOT NULL default '0', bramki_stracone int(10) unsigned NOT NULL default '0', wygrane int(11) NOT NULL default '0', remisy int(11) NOT NULL default '0', przegrane int(11) NOT NULL default '0', punkty int(10) unsigned NOT NULL default '0', PRIMARY KEY (id_teamu) ) TYPE=MyISAM; CREATE TABLE alpn_zawodnicy ( id_zawodnika int(10) unsigned NOT NULL auto_increment, id_teamu int(10) unsigned NOT NULL default '0', nazwisko varchar(255) NOT NULL default '', pozycja set('Bramkarz','Obrońca','Pomocnik','Napastnik') NOT NULL default '', bramki int(11) NOT NULL default '0', bramki_samobojcze int(11) NOT NULL default '0', zolte int(10) unsigned NOT NULL default '0', czerwone int(10) unsigned NOT NULL default '0', pauzuje_od int(11) NOT NULL default '0', pauzuje_do int(11) NOT NULL default '0', PRIMARY KEY (id_zawodnika) ) TYPE=MyISAM; Po dluższym myśleniu, wykombinowałem coś takiego: Kod SELECT SUM(alpn_zawodnicy.zolte) AS k_zolte, SUM(alpn_zawodnicy.czerwone) AS k_czerwone, (SUM(alpn_zawodnicy.zolte)*3+SUM(alpn_zawodnicy.czerwone)*6) AS punkty, alpn_druzyny.liga, alpn_druzyny.nazwa
FROM alpn_zawodnicy, alpn_druzyny WHERE liga='I' AND alpn_zawodnicy.id_teamu=alpn_druzyny.id_teamu GROUP BY alpn_zawodnicy.id_teamu ORDER BY punkty DESC I teraz tak. wyniki wygladaja bardzo dobrze, aż sam się dziwię, ale mam pytanie - czy te zapytanie jest OK, czy mozna je w jakis sposob zoptymalizowac? Bo napisac można wszystko, ale nie wszystko musi działąć optymalnie.. I o to własnie pytam - czy to jest optymalne? A pytam Was dlatego, że strona ALPN to jest pierwszy projekt, w którym stosuję aż tak (lame...) skomplikowane zapytania. I szczerze powiedziawszy jesli sie okaże że te bazgroły powyżej są ok. bedę mogł przepisać kilka innych selectów, które robiłem "aby były" ![]() -------------------- |
|
|
![]() |
![]()
Post
#2
|
|
![]() Grupa: Przyjaciele php.pl Postów: 398 Pomógł: 0 Dołączył: -- Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Wyjaśnienie do tabelki EXPLAIN:
Każdy rekord w tej tabeli to tabela, którą MySQL musi przejrzeć wykonując twoje zapytanie. Im jest ich mniej tym lepiej. table - Nazwa tabeli type - Rodzaj złączenia tabel. W twoim przypadku jest eq_ref - to dobrze, ponieważ jest to najwydajniejsze złączenie typu jeden-do-wielu; oraz ALL - to niedobrze, bo MySQL leci po wszystkich wierszach tabeli. Warto ograniczyć zakres jakimś indeksem. W twoim przypadku mógłby dość indeks następujący: Kod CREATE INDEX id_teamu ON alpn_zawodnicy(id_teamu); . To powinno ograniczyć egzaminowanie tabeli zawodników do teamu z którego są, czyli ALL powinno zmienić się na ref.
possible_keys - Indeksy które MySQL widzi i bierze pod uwagę kiedy zabiera się za sortowanie. key - Indeksy których MySQL użył. Jeśli wyraźnie widać, że nie zorientował się prawidłowo i wiemy lepiej którego indeksu należało użyć, możemy go do tego zmuszać (vide myisamchk --analyze oraz USE INDEX/IGNORE INDEX) - nieco wyższa szkoła jazdy. key_len - Długość klucza. Krótkie klucze są szybsze. Jeśli klucz jest wielokolumnowy MySQL przycina go jeśli może. ref - Jaki klucz obcy (lub stałą) użyto do wyboru rekordów w tej tabeli. rows - Ilość rekordów, które MySQL ostatecznie musi przejrzeć. Im mniej tym lepiej. Można przyjąć, że jeśli mamy kilka rekordów w wyniku EXPLAIN to kolejne pola rows można przez siebie pomnożyć by określić złożoność zapytania. extra - Dodatkowe informacje o użytych mechanizmach. U ciebie jest: Using temporary - użycie tymczasowej tabeli. Negatywnie wpływa na wydajność. Najczęstszym powodem pojawienia się tego mechanizmu jest sortowanie wg. innego pola niż następuje agregacja. U ciebie tak niestety jest i nie widzę za bardzo możliwości obejścia tego. Using filesort - dodatkowy przebieg wymagany przy sortowaniu. Wynika z tego, że sortujesz po dynamicznie tworzonym polu. Negatywnie wpływa na wydajność. Where used - przycięcie zakresu klauzulą where. Pozytywny objaw. Możesz spróbować użyć konstrukcji z LEFT JOIN'em i porównać wyniki. Kod SELECT SUM(alpn_zawodnicy.zolte) AS k_zolte, SUM(alpn_zawodnicy.czerwone) AS k_czerwone, (SUM(alpn_zawodnicy.zolte) * 3 + SUM(alpn_zawodnicy.czerwone) * 6) AS punkty, alpn_druzyny.liga, alpn_druzyny.nazwa
FROM alpn_druzyny LEFT JOIN alpn_zawodnicy USING(id_teamu) WHERE liga='I' GROUP BY alpn_druzyny.id_teamu ORDER BY punkty DESC; ![]() -------------------- cease this long, long rest / wake and risk a foul weakness to live / when it all comes down / watch the smoke and bury the past again / sit and think what will come / raise your fears and cast them all away
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 14.08.2025 - 18:49 |