Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Proste zapytanie prosta optymalizacja :)
little_MASTER
post
Post #1





Grupa: Zarejestrowani
Postów: 29
Pomógł: 0
Dołączył: 8.12.2008

Ostrzeżenie: (0%)
-----


Witam wszystkich!
Mam malutki problem odnośnie zapytania.
Otóż mam zapytanko:
  1. SELECT r.reg_nazwa AS region, w.woj_nazwa, o.typ, o.nazwa, o.ulica, o.kod, o.miasto, o.email, o.telefon, o.www, o.opis, o.notatki, o.cenaszkolenia, o.zdjecie FROM osoby o LEFT JOIN regiony r ON o.reg_id=r.reg_id LEFT JOIN wojewodztwa w ON o.woj_id = w.woj_id WHERE wew_id='E000001'

Które wybiera jakieś tam szczegóły z tabeli osoby, a że region jest jako id to wypadałoby pobrać nazwę z innej tabeli, podobnie dla województw.
Ogółem zapytanie działa (IMG:style_emoticons/default/smile.gif)

Ale...
To jedno zapytanie dla jak na razie 100 rekordów w tabeli osoby wykonuje się w 0,0006 sekundy (czyli dość szybko w/g mnie).

Tylko zastanawiam się jak to coś zoptymalizować, tzn same zapytanie, czy muszę robić dwa razy JOIN i czy koniecznie musi być LEFT, może jakiś inny.

A tak na marginesie czy w przypadku takich zapytań ma znaczenie jak ustawiłem indexy?

Dla tabeli osoby mam jako indexy: wew_id jako primary, reg_id i woj_id jako pomocnicze.

W razie potrzeby przedstawię strukturę wizualnie, choć wydaje mi się że jest ona dość zrozumiała (IMG:style_emoticons/default/smile.gif)

Prosiłbym o pomoc, wykładowca dość poważnie ocenia optymalizację zapytań, a chciałbym to jakoś spokojnie zaliczyć (IMG:style_emoticons/default/tongue.gif)

Z góry dzięki za pomoc.

//EDIT
Stworzyłem jeszcze takie zapytanko:
  1. SELECT r.reg_nazwa AS region, w.woj_nazwa, o.typ, o.nazwa, o.ulica, o.kod, o.miasto, o.email, o.telefon, o.www, o.opis, o.notatki, o.cenaszkolenia, o.zdjecie FROM osoby o, regiony r, wojewodztwa w WHERE o.reg_id=r.reg_id AND o.woj_id = w.woj_id AND wew_id='E000001'

I teraz kolejne pytanie: które z tych dwóch jest lepsze? Które w przypadku dużej ilości rekordów będzie lepsze?

Wiem że mogę wygenerować 100tys albo i więcej rekordów i to sprawdzić, ale jednak wolałbym poradzić się doświadczonych koderów najpierw (IMG:style_emoticons/default/wink.gif)

Ten post edytował little_MASTER 25.10.2011, 11:37:00
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
piotr.kazmiercza...
post
Post #2





Grupa: Zarejestrowani
Postów: 47
Pomógł: 10
Dołączył: 1.03.2010
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Ogólnie jeżeli zależy Ci na prędkości działania bazy to:

1) Olej postacie normalne w bazie.

  1. SELECT r.reg_nazwa AS region, w.woj_nazwa, o.typ, o.nazwa, o.ulica, o.kod, o.miasto, o.email, o.telefon, o.www, o.opis, o.notatki, o.cenaszkolenia, o.zdjecie FROM osoby o LEFT JOIN regiony r ON o.reg_id=r.reg_id LEFT JOIN wojewodztwa w ON o.woj_id = w.woj_id WHERE wew_id='E000001'


Zmień na

  1. SELECT o.reg_nazwa AS region, o.woj_nazwa, o.typ, o.nazwa, o.ulica, o.kod, o.miasto, o.email, o.telefon, o.www, o.opis, o.notatki, o.cenaszkolenia, o.zdjecie FROM osoby o WHERE wew_id=1


Czyli co zmienić i dlaczego:
Jeżeli robisz dużo zapytań gdzie szukasz np informacji o użytkowniku jak w tym przypadku, wszystko co się da umieść w tej samej tabelce. Z zapytania widzę że potrzebujesz przy wyjmowaniu jedynie nazwę województwa w takim razie nie ma potrzeby JOINa. Jest to bardzo "sztywne" rozwiązanie jednak w znaczącym stopniu przyśpiesza zapytania.

2) Użyj MEMORY

Ogólnie jeżeli przechowujesz w bazie dane które będą rzadko/nigdy nie zmieniały używaj dla nich typu tablic: MEMORY. Tablice te będą przechowywane wyłącznie w pamięci więc dostęp do nich będzie dużooo szybszy. W tym wypadku do MEMORY wstawiasz rediony i wojewodztwa

3) Użyj widoków

Jeżeli spodziewasz się częstego odpytywania o dane. Stwórz z tych zapytań z Joinami gotowe widoki (View). Są to tymczasowe tabele utworzone z zapytań. Przydatne i szybkie rozwiązanie.

Wybór rozwiązania zależy od
- ilości danych (100tys to bardzo mało, zabawa zaczyna się przy 30 mil.)
- częstotliwości dodawania nowych danych (predykcja)
- częstotliwości aktualizacji istniejących danych(predykcja)
Go to the top of the page
+Quote Post
little_MASTER
post
Post #3





Grupa: Zarejestrowani
Postów: 29
Pomógł: 0
Dołączył: 8.12.2008

Ostrzeżenie: (0%)
-----


Wszystko jest w tabeli użytkownicy, jedyne co potrzebuję to nazwę regionu z którego pochodzi użytkownik (relacja n-1 wielu użytkowników jeden region, czyli użytkownik może mieć wybrany tylko jeden.) podobnie z województwami.

Regiony będą się zmieniały sporadycznie, tzn czasami dojdą nowe, województwa, hmm to po jakiś zmianach administracyjnych w Polsce (IMG:style_emoticons/default/tongue.gif)

Czyli rozumiem żeby robić SELECTA z bazy osoby normalnie, a co z regionami i województwami? Jakiś przykładzik zastosowania tego MEMORY? (IMG:style_emoticons/default/wink.gif)

Osoby będą dodane raz (przeze mnie na potrzeby zaliczenia:)), ale w założeniu mam, że kilka osób może dodawać/aktualizować dane odnośnie osób z poziomu panelu administracyjnego, chodzi o to żeby mieć poziomy uprawnień, ale to poza tematem troszkę.
Wykładowca wpisał mi że powinna być możliwość dodawania/edycji/usuwania przez kilka osób na raz.

A odnośnie edycji/usuwania: jak zabezpieczyć tabelę osoby przed edycją/usunięciem rekordu w tym samym czasie?
Czyli ktoś edytuje rekord a druga osoba chce go usunąć, albo ktoś edytuje, a druga osoba chce to samo zrobić.
Myślałem o tym żeby zrobić timestamp w momencie kiedy zaczynamy edytować, tzn ktoś wchodzi w edycję jakieś osoby, w rekordzie w polu timestamp ustawia się czas+pół godziny i mamy czas na edycję, po zaptwierdzeniu zmian timestamp robimy null. W razie wyłączenia kompa/przeglądarki po pół godziny edycja będzie dostępna dla kogoś innego.

A co do widoków, to czy dużo pomagają przy częstych zapytaniach? Przykładowo 4 razy na sekundę? Strona i tak jest na smarty więc jest cachowana, ale zastanawiam się czy dodatkowo cachować wyniki z zapytań z bazy?

//BTW
Co z tabelą na silniku MEMORY kiedy zrobimy restart serwera? Tzn w tym przypadku mojego kompa? Czy dane są usuwane? Chyba tak skoro są w pamięci tylko. Ale czy są przywracane po ponownym starcie serwera MySQL?

Ten post edytował little_MASTER 25.10.2011, 19:28:12
Go to the top of the page
+Quote Post
piotr.kazmiercza...
post
Post #4





Grupa: Zarejestrowani
Postów: 47
Pomógł: 10
Dołączył: 1.03.2010
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Jeżeli to na jakieś zaliczenie to pomiń moją propozycje z umieszczeniem nazw regionów i województw w jednej tabeli bo Cie wykładowca na pal nabije (IMG:style_emoticons/default/smile.gif) .

Cytat(little_MASTER) *
Czyli rozumiem żeby robić SELECTA z bazy osoby normalnie, a co z regionami i województwami? Jakiś przykładzik zastosowania tego MEMORY? (IMG:style_emoticons/default/wink.gif)


MEMORY to tylko typ tablicy robisz do tego takie same zapytania jak każde inne.

Cytat(little_MASTER) *
A odnośnie edycji/usuwania: jak zabezpieczyć tabelę osoby przed edycją/usunięciem rekordu w tym samym czasie?
Czyli ktoś edytuje rekord a druga osoba chce go usunąć, albo ktoś edytuje, a druga osoba chce to samo zrobić.
Myślałem o tym żeby zrobić timestamp w momencie kiedy zaczynamy edytować, tzn ktoś wchodzi w edycję jakieś osoby, w rekordzie w polu timestamp ustawia się czas+pół godziny i mamy czas na edycję, po zaptwierdzeniu zmian timestamp robimy null. W razie wyłączenia kompa/przeglądarki po pół godziny edycja będzie dostępna dla kogoś innego.


Poczytaj o SQL Transaction

Cytat(little_MASTER) *
A co do widoków, to czy dużo pomagają przy częstych zapytaniach? Przykładowo 4 razy na sekundę? Strona i tak jest na smarty więc jest cachowana, ale zastanawiam się czy dodatkowo cachować wyniki z zapytań z bazy?


Widoki warto używać w momencie jak musisz robić JOIN na dużych tablicach. O ile to przyśpiesza to ciężko powiedzieć wszystko zależy od struktury danych.

//BTW
Cytat(little_MASTER) *
Co z tabelą na silniku MEMORY kiedy zrobimy restart serwera? Tzn w tym przypadku mojego kompa? Czy dane są usuwane? Chyba tak skoro są w pamięci tylko. Ale czy są przywracane po ponownym starcie serwera MySQL?


Trzeba to samemu oprogramować, że po restarcie SQL'a wstawiasz do tablic MEMORY dane na nowo. Trochę uciążliwe ale bardzo szybkie.
Go to the top of the page
+Quote Post
little_MASTER
post
Post #5





Grupa: Zarejestrowani
Postów: 29
Pomógł: 0
Dołączył: 8.12.2008

Ostrzeżenie: (0%)
-----


Cytat(piotr.kazmierczak @ 25.10.2011, 23:32:18 ) *
Poczytaj o SQL Transaction


Co to transakcje to wiem (IMG:style_emoticons/default/smile.gif) (Tak mi się przynajmniej wydaje (IMG:style_emoticons/default/tongue.gif) )
mysqli ma mechanizm do tego. Mam zrobione tak:
  1. //############### INSERTION ###############
  2. mysqli_autocommit($this->link, false);
  3. mysqli_query($this->link, "SET NAMES 'utf8'");
  4. $q = "insert into osoby zapytanie";
  5.  
  6. mysqli_query($this->link, $q);
  7. if (mysqli_errno($this->link))
  8. {
  9. mysqli_rollback($this->link);
  10. return - 1;
  11. } else
  12. {
  13. $newID = mysqli_insert_id($this->link);
  14. $q = "UPDATE obiekty SET wew_id=CONCAT('E',substring('00000',length(osoba_id)),osoba_id) WHERE obiekt_id = $newID";
  15.  
  16. $wynik = mysqli_query($this->link, $q);
  17. if (mysqli_errno($this->link))
  18. {
  19. mysqli_rollback($this->link);
  20. return - 1;
  21. } else
  22. {
  23. mysqli_commit($this->link);
  24. return 1;
  25. }
  26. }
  27. return - 1;


Ale bardziej chodzi mi o edycje osób.
Tzn i tak muszę zrobić selecta żeby wypełnić formularz edycji, a po zmianie czegokolwiek zrobić update. No chyba oczywiste jest (IMG:style_emoticons/default/smile.gif)
Tylko jak to zabezpieczyć żeby dwie osoby nie edytowały w tym samym czasie tej samej osoby.
Sytuacja jest prosta wydaje mi się, żeby jedna osoba nie zastąpiła przypadkiem pracy innej.

Zrobić jakiś timestamp w tabeli dodatkowo?

Co do tablic memory to chyba zostanę narazie na InnoDB, albo nawet zrezygnyje z transakcji i przejdę na MyISAM, bo z tego co wyczytałem przy operacjach typu select jest szybszy, a jak zaznaczyłem głównie będę wyświetlał dane, edycja będzie sporadyczna (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

Posty w temacie
- little_MASTER   Proste zapytanie prosta optymalizacja :)   25.10.2011, 11:30:14
- - nospor   Same joiny masz zrobione poprawnie. Co do indeksów...   25.10.2011, 11:36:40
- - luckyps   Cytat(little_MASTER @ 25.10.2011, 12:30...   25.10.2011, 11:41:45
- - little_MASTER   Tak wygląda tabelka z profilowania. Czy korzysta w...   25.10.2011, 11:42:21
- - nospor   Prosiłem o EXPLAIN a nie ok profilowanie   25.10.2011, 11:48:15
|- - little_MASTER   Cytat(nospor @ 25.10.2011, 12:48:15 )...   25.10.2011, 11:58:44
- - nospor   No i już widzisz które lepsze Jedno pobiera 1 rek...   25.10.2011, 12:03:10
- - luckyps   Cytat(little_MASTER @ 25.10.2011, 12:42...   25.10.2011, 12:04:51
|- - little_MASTER   Cytat(luckyps @ 25.10.2011, 13:04:51 ...   25.10.2011, 12:31:01
- - nospor   Co to za typy, ile ich będziesz miał, czy one są d...   25.10.2011, 12:38:27
- - little_MASTER   Typy to tak jakby kategorie, tzn osoba może być le...   25.10.2011, 13:47:19
- - nospor   To musisz dodać tabelę łączącą osobę z typem: osob...   25.10.2011, 13:49:15
|- - little_MASTER   Cytat(nospor @ 25.10.2011, 14:49:15 )...   25.10.2011, 14:55:27
- - piotr.kazmierczak   Ogólnie jeżeli zależy Ci na prędkości działania ba...   25.10.2011, 15:51:47
- - little_MASTER   Wszystko jest w tabeli użytkownicy, jedyne co potr...   25.10.2011, 18:33:52
- - piotr.kazmierczak   Jeżeli to na jakieś zaliczenie to pomiń moją propo...   25.10.2011, 22:32:18
- - little_MASTER   Cytat(piotr.kazmierczak @ 25.10.2011, 23...   26.10.2011, 09:49:37


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 3.10.2025 - 11:15