Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: czy widok moze spowolnic zapytanie?
Forum PHP.pl > Forum > Bazy danych > MySQL
misty
Czesc, mam takie pytani: mam tabele w ktorej jest dosc sporo danych. Mam przygotowany widok ktory mi z niej wyciaga jakies dam dane, max (czas), group by 2 pola oraz 1 join tam jest. Widok wyglada mniej wiecej tak:

  1. CREATE OR REPLACE VIEW test_v AS SELECT max(start_date), field_1, field_2, field_3, field_4
  2. FROM test_table_1
  3. LEFT JOIN test_table_2 ON test_table_2.id = test_table_1.test_table_2_id
  4. WHERE test_table_2_id IN (1,2,3,4,5,6,7,8,9,10)
  5. GROUP BY field_1, field_2


Zastanawiam sie, co w tym przypadku bedzie szybsze - czy za kazdym razem robienie select'a z tej tabeli (czyli parta kodu zaczynajaca sie od SELECT max..)
czy tez utowrzenie takiego widoku i robienie z niego selecta. Czy ten widok nie zabiera mi jakiegos cennego czasu? Lub czy moge sprawdzic (jak?) rzeczywisty czas wykonania zapytan? Bo z tego co sie orientuje to mysql cachuje zapytania, wiec wyniki ktore dostaje nie sa miarodajne.

Bede wdzieczna za wskazowki,
pzdr,
misty
alegorn
hmm.
mysle ze kluczem do odpowiedzi jest odpowiedz na pytanie, co chcesz zrobic z wynikami?
moze w podpunktach:

aktualnosc danych
ilosc odwolan do tych samych danych
dalsze obrabianie wynikow

jesli bedziesz znac odpowiedz na te kluczowe pytania - latwiej bedzie dac odpowiedz.

scenariusz 1
musze miec dostep do aktualnych danych, wyniki nie podlegaja dalszej obróbce po stronie mysql
odpowiedz: zapytanie, lub ewentualnie procedura.
procedure trzeba umiejetnie napisac (zreszta procedury to osobna kwestia)
byc moze, lepiej bedzie ci rozbic skomplikowane zapytanie na kilka mniejszych? bedzie o wiele wydajniej (kwestia wielowatkowosci mysql)

scenariusz 2
musze miec aktualne dane, musze obrabiac dalsze dane
odpowiedz: widok
tracisz odrobine na wydajnosci, ale zyskujesz latwy dostep do aktualnych danych

scenariusz 3
chce miec szybki wydajny i wygodny dostep do danych. dane moga byc aktualizowane np. co 30min.
odpowiedz:
tabele tymczasowe, lub tabele generowane
tabele tymczasowa - zyskujesz najszybszy dostep do danych (wypelniane sa RAZ NA SESJE), klopotem jest odpowiednie zainicjowanie takiej tabeli, ale to do zrobienia.
tabele generowane(nie znam dobrej nazwy, chodzi o tabele z zrzutem danych) - cos a'la tabela tymczasowa, tyle ze nie generujesz tego per sesja - tylko per czas.
musisz tutaj wykonac dodatkowy skrypt ktory co okreslony interwal czasu bedzie wypelnial dane (oczywiscie mija sie z celem jesli musisz miec aktualne dane np co 5 min. to dziala najlepiej raz na kilkadziesiat minut - raz na pare godzin/raz na dzien) skrypt odpalasz albo jako events, albo z crona.

oczywiscie to schematy rozwiazan, to zalezy tak naprawde co potrzebujesz - i co potrafisz.

j.


ps do testowania zapytan uzywal SQL_NO_CACHE w zapytaniu, nie bedziesz wtedy kozystac z qc, a tak naprawde explain prawde ci powie
misty
czesc,
dzieki za obszerna odpowiedz! Wpierw skorzystam z Twoich podpowiedzi do sprawdzenia faktycznego czasu aktualnych zapytan. Moze jednak samo zapytanie (z glownej tabeli) jest wolne, a widok nie ma az tak wielkiego wplywu? Jak to sprawdze to bede mogla podjac dalsze decyzje.
dzieki!

alegorn
widok de facto nie sprawi ze dane beda ci sie szybciej ladowac, mozesz sobie o tym myslec ze to w pewnym sensie niejako alias na zapytanie.
nie powinno byc znaczacej roznicy, niewielka bedzie spowodowana pewnie tym ze w widoku optymalizator wstepnie juz poprawi to zapytanie. ale to beda nadal czasy na tyle bliskie, ze w praktyce bez wiekszego znaczenia.

widok sprawia, ze dane te sa lepiej 'opakowane' przydaje sie gdy chcesz sie bawic z uprawnieniami, lub innych dziwnych sytuacjach...
tyle ze widok sam w sobie nie sprawi ze zapytanie bedzie sie wykonywac znaczaco szybciej...

j.

ps bedzie to widac w explain - nie bedzie zadnej roznicy, jesli wykonasz explain na widoku, czy na samym zapytaniu.
misty
Czesc, potestowalam troche i wychodzi na to ze to nie widok spowalnia. Co ciekawe-z uzyciem widoku czas wyszedl mi 0,67 sek szybszy, troche nie wiem jak to mozliwe, ale tak czy siak - nie w widoku tkwi problem. Problemem jest grupowanie. Ktorego niestety nie moge uniknac bo jest to kluczowe dla tego zapytania. Co ciekawe-nalozenie indeksow na pola po ktorych grupuje nic nie dalo. Masz moze jakis pomysl na grupowanie?


pzdr,
misty
alegorn
minimalnie szybciej (prawdopodobnie kwestia optymalizatora i tym podobnych, w razie czego w profilowaniu da sie to dokladnie sprawdzic)
jakiego rzedu sa te czasy? bijemy sie o sekundy? milisekundy?

tak naprawde musialbym wynik explain'a zobaczyc by ocenic, ale czysto teoretycznie, sprawca najwiekszego obciazenia w kolejnosci to:

o ile dobrze widze - potrzebujesz do tego tabel tymczasowych (w explain powinno byc to widac), jesli w tabeli masz duzo danych - tabele te musza byc zapisane na dysku czyli masz extra operacje IO
operacje wyliczeniowe(max - w jakim formacie masz ta kolumne?),
nastepnie agregujace (group by)

oczywiscie to co napisalem zalezy od tego jakie masz tabele, ile danych, jakie indexy (jakie zalozone - a pamietaj ze index potrafi spowalniac aplikacje)
tak naprawde od calej masy czynnikow..

powiedz mi do czego to potrzebujesz? do aplikacji webowej?
jak bardzo potrzebujesz aktualnych danych, i czy sa one czesto modyfikowane ?
byc moze najlepszym bedzie zastosowanie tabel tymczasowych... ale to juz kwestia z projektowania aplikacji/bazy
jesli mozesz - podaj strukture tych tabel, bedzie latwiej odpowiedziec.

ewentualnie, jesli masz taka mozliwosc rozbij to zapytanie na kilka mniejszych, wykorzystaj wielowatkowosc mysql'a, rozwiazan jest naprawde przynajmniej kilka.

j.
misty
Czesc, walczymy o sekundy. Pole na ktorym jest max to jest pole typu datetime i na tym polu mam indeks. Ale jak pisalam - problemem jest groupBy. Samo zapytanie trwa 12 sekund. Gdy zas usune groupBy czas mi spadl do 3,6sekundy.. Wiec roznica jest ogromna! Jedyne co mi przychodzi do glowy to "select *" i obrobka po str php. Chociaz tego chcialabym uniknac :/

Jesli chodzi o aktualizacje danych - na tej tabeli nie ma update'ow, sa tylko inserty. Ile tego wchodzi dziennie, niestety nie wiem, ale nie jakos duzo, mysle ze kilkadziesiat insertow dziennie.

Usuniecie funkcji max tez oczywiscie przyspiesza. Z 12sekund spadlo mi na 8.9 sekund. Jesli chodzi o ilosc danych to w tym momencie jest ich 1,074,027
alegorn
najprawdopodobniej nie uda ci sie uzyskac satysfakcjonujacego wyniku w tej postaci.
z prostego faktu - operacje jakie wykonujesz - sa najzwyczajniej w swiecie kosztowne.
byc moze gdyby ci sie udalo ograniczyc ilosc rekordow - wtedy czas bylby sensowniejszy.

jesli potrzebujesz takie wyniki uzyskiwac w szybkim czasie, a nie mozesz z niczego zrezygnowac - bedziesz musiala zmienic koncepcje.

proponowalbym:

1. utworzyc tabele z cache.
2. utworzyc procedure wypelniajaca ta tabele aktualnymi danymi.
3. utworzyc events odpalajacy owa procedure co dany interwal czasu

lub

2. wypelnic tabele danymi
3. po kazdym insercie aktualizowac dane.

wtedy zapytanie pobierajace wynik - dzialalo by ci rewelacyjnie szybko.
podpowiem, ze da sie calosc przeprowadzic w taki sposob, by tabela z cache praktycznie nie byla blokowana przez procedury aktualizacji.
choc oczywiscie to takze zalezy od serwera jak posiadasz.

co wybrac? to zalezy pd serwisu. ja, gdy project manager próbuje mi wmówić że potrzebuje miec online jakies county sumy itp - staram sie dowiedziec co rozumie pod pojeciem online.
czasem nawet 5 min. dokladnosc jest juz zbawieniem. najzwyczajniej w swiecie - operacje agregujace sa kosztowne, i nie ma sily, by na duzej ilosci rekordow wykonywaly sie w sensownym czasie.

jasne, da sie jeszcze co nieco powalczyc sprzetowo (podrasowac na maxa serwer by mogl nasza tabele tymczasowa trzymac w pamieci - nie na dysku), ale to juz jest kosztowna zabawa, i na krótka mete.

trudno mi jest powiedziec co bedzie lepsze, byc moze szybciej bedzie wykonac to po stronie php, choc i tak, przemielic 1kk rekordow - to nie jest latwa zabawa.

bez dokladniejszej analizy - nie bede mogl pomoc, chyba nikt na forum zreszta nie pomoze bez wgladu w explain'a itp.
w tej chwili jedyne co moge doradzic - to szukanie innego rozwiazania.

j.
misty
Czesc,
dzieki ponownie za obszerna wypowiedz smile.gif Jesli chodzi o wypelnianie tej tabeli danymi - robia to inne programy zewnetrzne, wiec ja nie mam tutaj mozliwosci manipulacji. Sprzet stoi zupelnie gdzie indziej i nie mam mozliwosci nawet sugerowania jego podrasowania. Tak mysle wlasnie ze niestety tak to zostanie juz jak jest teraz.

pzdr,
misty
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.