Artykuł ten jest pierwszym z naszej nowej serii poświęconej optymalizacji. Znajdziecie tu trochę teorii i ogólnych zasad, jakimi należy kierować się przy poprawianiu własnego kodu. Celem całej linii tekstów jest nakreślenie osobom piszących w PHP i korzystających z możliwości MySQL reguł oraz praktycznych przykładów bardziej wydajnych metod programowania.
Definicja optymalizacji
Optymalizacją w informatyce nazywamy ciąg działań, dzięki którym osiągamy poprawę wydajności danego programu. Chrakteryzuje się to przede wszystkim zmniejszeniem użycia pamięci maszyny, na której się on znajduje oraz zwiększeniem szybkości działania samego programu.
Zwiększenie wydajności można uzyskać na kilku różnych płaszczyznach, poczynając od modernizacji i uproszczenia działań matematycznych lub fizycznych w stosowanych algorytmach, przechodząc przez wymianę użytych w aplikacji funkcji, konstrukcji językowych oraz kwarend, a kończąc na konstruowaniu działań w kilku językach, poprzez zastosowanie programowania hybrydowego.
Na płaszczyźnie tworzenia aplikacji internetowych kod można także dostosowywać pod kątem zgodności ze standardami oraz wyszukiwania przez wyszukiwarki internetowe, co można podpiąć pod kategorię pozycjonowania.
Rysunek 1: przykładowy proces optymalizacji dla wyszukiwarek internetowych.
Do ostatniego kryterium należy także inny typ optymalizacji - treści. Dla użytkownika danej strony jest on o tyle ważny, że zwiększa przystępność znajdujących się na niej zasobów.
Dlaczego warto optymalizować już w fazie planowania?
Jeżeli przeznaczeniem nowo budowanego serwisu jest dłuższy, a nawet komercyjny byt, warto planować kwestie wydajnościowe już we wstępnej fazie projektowania. Nie zaoszczędzi to wszystkich, przyszłych poprawek w kodzie, ale może pozwolić na uniknięcie potrzeby modyfikacji całego lub większych części skryptu.
Przede wszystkim należy przemyśleć to, jaki jest cel tworzonej przez nas usługi, do kogo ją kierujemy i jakie będziemy mieli wobec niej oczekiwania. Odpowiedzi na te pytania pozwolą na wstępne ocenienie, jakiego typu serwer będzie potrzebny, jakie oprogramowanie będzie niezbędne do pracy, czy jakie obciążenie będzie mogła generować strona - i to ze sporym wyprzedzeniem czasowym. Warto więc poświęcić trochę czasu na trzeźwą analizę celów, możliwości i potrzeb.
Rysunek 2: techniczny proces związany z optymalizacją w projektowaniu.
Na co warto więć zwrócić uwagę, kalkulując wymagania? Przy dużych rozwiązaniach - na przykład na alokowanie danych względem oczekiwań odnośnie do generowanego obciążenia. W takich przypadkach stworzony kod PHP może być tylko małą przyczyną tworzonego problemu, a co za tym idzie - należy skupić się na zapytaniach SQL. Można więć wysunąć wniosek, że czasem skorzystanie z metody zapisu do plików może być bardziej wydajne niż operowanie na jakiejkolwiek bazie danych.
Ładowanie







Browser: Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
dAREuS
Browser: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.70 Safari/533.4
Pozdrawiam i czekam na dalsze części artykułu.
http://jaceksmolak.pl
Browser: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)
Z praktycznego punktu widzenia nic nie wnosi. Ale wystarczy przeczytać temat żeby dostrzec, że nie tej płaszczyzny on dotyczy. I wprost przeciwnie, warto planwować target i pewne kwestie dotyczące samego kodu, i przed, i w trakcie jego pisania. Inaczej wspominany zleceniobiorca, jeżeli będzie miał o tym jakiekolwiek pojęcie, może zarządać przepisania go od nowa widząc to co stworzył bez rozmysłu programista. Wszystko to podsumował w jednym zdaniu Darek.
Co do wypowiedzi @Jacka S. - chętnie posłucham wszelkich sugestii co do następnych części serii :]
http://m1chu.eu | http://utnij.eu | http://after-all.eu | http://regexp.pl/
Browser: Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
Optymalizacja zapytania z count() też moim zdaniem niewiele pokazuje, prawie na 100% testowano na typie tabeli z silnikiem MyIsam, a on przechowuje liczbę wierszy wewnętrznie i wykorzysuje je przy zapytaniach bez warunków, zastosujcie warunek WHERE i już nie bedzie takich różnic czasowych
Browser: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
Czy była by możliwość załączenia przy wynikach jeszcze czasów z count + select (wybierający dane) i SQL_CALC_FOUND_ROWS + FOUND_ROWS() ?
Browser: Opera/9.80 (Windows NT 6.1; U; pl) Presto/2.5.29 Version/10.60
Przykładowo: ostatnio znajomy administrator poprosił mnie o to, żebym z dość sporego zapytania SQL zdjął ORDER BY oraz LIMIT i przekazał to do PHP. Wynik nie był mały (w skrajnych przypadkach liczący kilka tysięcy rekordów), ale MySQL został odciążony i to w znacznym stopniu (oraz szybciej wykonało się zapytanie), przy małym, dodatkowym, obciążeniu PHP.
Wczoraj trafiłem na taki temat: http://codingforums.com/showthread.php?t=183781
Może przytoczę konkretny cytat:
"I just created a MySQL DB with 10,000,000 records, as a test case. And
I'm doing a range query (WHERE externalid = 777 AND timefield BETWEEN x
AND y) and by making a composite key on (externalid, timefield) I was
able to find a set of 60 matching records in roughly 1 millisecond. Yet
if the composite key is reversed... (timefield, externalid) ... then
the query takes 1000 times longer!!!!
MySQL is *especially* sensitive to the order of fields in a key, so
experiment, experiment, experiment. And don't forget about EXPLAIN."
Także szerszy temat o wykorzystaniu indeksów bym prosił :)
A od siebie jeszcze kilka linków:
http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html
http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html
http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html
Pozdrawiam!
http://jaceksmolak.pl
Browser: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)
Dodatkowo można napisać chociaż ze dwa zdania (z przykładem) o lazy initialization.
Pozdrawiam!
http://jaceksmolak.pl
Browser: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)
Bardziej życiowe przykłady pojawią się w kolejnych częściach. Te dwa (kompletnie wyimaginowane pod względem stopnia użyteczności) mają tylko pokazać osobom które nigdy o optymalizacji nie słyszały, gdzie może leżeć punkt zaczepienia w tym temacie. Nic po za tym, takie przygotowanie do kontynuacji, gdzie będzie o tym więcej i konkretniej.
@melkorm:
Te przykłady, w szerszej formie będą w części dotyczącej tego aspektu. Wtedy na pewno zamieszczę czasy, szersze tłumaczenia, itd.
@Jacek S.:
Dzięki bardzo za komentarz. Zabiorę go pod uwagę jak już będę "skrobał" :]
http://m1chu.eu | http://utnij.eu | http://after-all.eu | http://regexp.pl/
Browser: Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
1. Count(*) na tabeli myisam jest rzeczywiście szybkie przy zapytaniach bez klauzuli where ponieważ licznik rekordów jest przechowywany wewnętrznie i nie ma potrzeby skanowania tabeli.W każdym innym wypadku mysql i tak musi przeskanować tabele, ewentualnie uzyć indeksu.
2. count(*) na tabeli innoDb działa znacznie wolniej od myisam
Browser: Opera/9.80 (X11; Linux i686; U; pl) Presto/2.6.30 Version/10.60
Browser: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 ( .NET CLR 3.5.30729)
Browser: Opera/10.60 (X11; Linux x86_64; U; pl) Presto/2.6.30 Version/10.60
Bazy danych to dużo teorii, a dopiero później SQL-owe sztuczki.
Browser: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.4 SUSE/5.0.372.0-1.1 (KHTML, like Gecko) Chrome/5.0.372.0 Safari/533.4
pytam o to bo spotkałem się z osobami przyzyczajonymi do widoków z innych baz danych gdzie pewnie one sa materializowane jako osobne tabele i mają inne możliwości. tylko, że cięzko to przetłumaczyć takim osobom a miałem już okazję oglądać plikację gdzie widoki były nasepnie używane w zapytaniach typu JOIN z kolejnymi widokami , itp itd i działało to koszmarnie wolno.
co mnie zdziwiło to nie był pierwszy raz gyd spotykam programistów którzy chcąprzyspieszać działanie Mysql za pomocą używaia widoków
Browser: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 ( .NET CLR 3.5.30729)
Browser: Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
Browser: Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1.1 Firefox/3.5.9
Browser: Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
widok "nie musi spowalniać" ale może i to jest właśnie problem, ze wiele osób tego nie zauważa, ze moze spowodowac to prace na nieindeksowanych danych
Browser: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729)