Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Optymalizacja bazy danych
wachcio
post
Post #1





Grupa: Zarejestrowani
Postów: 45
Pomógł: 0
Dołączył: 17.07.2011

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


Witam

Mam bazę danych którą opisałem wcześniej Temat: Wyszukiwanie danych w kilku tabelach
Na razie składa się ona z 11 tabel gdzie każda przechowuje w kolumnach numer porządkowy, datę odczytu i wartość odczytu z różnych czujników np temperatury. Dane gromadzone są od maja tego roku a odczyty co minutę. Daje to na tę chwilę ok 250 000 rekordów na każdą tabelę czyli niecałe 3 000 000 rekordów w bazie. Zrobiłem sobie prostą stronę aby wyświetlać jak na razie:
- ostatni odczyt np.
  1. $temp_raspberry_pi = mysql_query ("SELECT `value`,`time` FROM `Raspberry_Pi` ORDER BY `Raspberry_Pi`.`time` DESC LIMIT 2");
  2. $temp_raspberry_pi = mysql_fetch_assoc($temp_raspberry_pi);

- najwyższy odczyt z dziś
  1. $hi_temp_raspberry_pi = mysql_query ("SELECT `value`,`time` FROM `Raspberry_Pi` WHERE DATE( `time` ) = CURDATE( ) ORDER BY `Raspberry_Pi`.`value` DESC LIMIT 2");
  2. $hi_temp_raspberry_pi = mysql_fetch_assoc($hi_temp_raspberry_pi);

- najniższy odczyt dziś
  1. $low_temp_raspberry_pi = mysql_query ("SELECT `value`,`time` FROM `Raspberry_Pi` WHERE DATE( `time` ) = CURDATE( ) ORDER BY `Raspberry_Pi`.`value` ASC LIMIT 2 ");
  2. $low_temp_raspberry_pi = mysql_fetch_assoc($low_temp_raspberry_pi);


Udało mi się uporać z problemami przedstawionymi w poprzednim poście ale wyświetlanie tych wyników dla wszystkich 11 tabel trwało ok 14 sek (IMG:style_emoticons/default/sad.gif) Poczytałem jak mogę zoptymalizować bazę. Dodałem indeksy na kolumny z datą i wartością odczytu. W zapytaniu SELECT uściśliłem potrzebne mi kolumny oraz dodałem klauzulę LIMIT. Strona wczytuje się teraz ok 6,5 sek czyli sporo mniej ale i tak dość długo. Zauważyłem, że najwięcej czasu zajmują zapytania wybierające rekordy z dziś. Wiadomo, że z czasem problem będzie narastał bo i danych będzie przybywało. Poza tym planuję dodawać nowe czujniki...
Co jeszcze mogę zrobić aby poprawić wydajność?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
pmir13
post
Post #2





Grupa: Zarejestrowani
Postów: 282
Pomógł: 89
Dołączył: 12.04.2011

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


Z tego co autor napisał wynika, że tabele są dla różnych czujników, a każda ma dane od początku, więc WHERE jest niezbędny by mieć dane z konkretnego dnia.
Co do optymalizacji pierwszym problemem jest tutaj fakt, że w tym warunku WHERE wykonujemy funkcję na kolumnie, co nie kwalifikuje indeksu na tej kolumnie do wykorzystania. Można próbować przepisać to w ogólnej postaci jako na przykład
  1. ... WHERE `time` BETWEEN '2016-08-01 00:00:00' AND '2016-08-01 23:59:59'

albo prościej dla dzisiejszego dnia o ile nie ma możliwości by były jakieś późniejsze wpisy:
  1. ... WHERE `time` > CURDATE()

jednak w najlepszym przypadku dostaniemy w explain type=range, a do tego nie da się potem podczepić następnej części indeksu do sortowania wartości. W zależności od ilości danych może to być szybsze niż pełen skan tabeli (type=all) czy bardziej prawdopodobny skan indeksu (type=index), jednak wciąż w obrębie dnia będziemy mieć sort by znaleźć maksymalną czy minimalną wartość.
Dopiero denormalizacja i wprowadzenie dodatkowej kolumny zawierającej wyłącznie datę bez czasu oraz wprowadzenie podwójnego indeksu na (data,wartość) umożliwi nam dla zapytania typu
  1. ... WHERE `date` = CURDATE() ORDER BY `value` DESC LIMIT 1

pełne wykorzystanie tego indeksu (w explain będzie type=ref oraz ref=const) i możemy mieć w tabeli pierdyliard rekordów a wynik dostaniemy bardzo szybko - mysql znajdzie konkretne miejsce z danymi po indeksie btree w logarytmicznym czasie.
Go to the top of the page
+Quote Post
trueblue
post
Post #3





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

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


Cytat(pmir13 @ 15.12.2016, 09:51:10 ) *
Z tego co autor napisał wynika, że tabele są dla różnych czujników, a każda ma dane od początku, więc WHERE jest niezbędny by mieć dane z konkretnego dnia.

Zgadza się, że są dla różnych czujników, ale nie wiem na jakiej podstawie wnioskujesz, że każdy czujnik ma dane z innych dni.
Z tego co napisał autor, każdy czujnik ma najświeższe dane (zbiera co minutę).
Tak więc WHERE jest niepotrzebny.
Ale może się zdarzyć sytuacja, że dany czujnik nie działa i jeśli chcemy wyświetlić dane tylko z dzisiejszego dnia. Wtedy rozwiązaniem może być sprawdzenie danych już na poziomie skryptu. Podobnie gdyby się jednak okazało, że dane są z różnych dni.
Go to the top of the page
+Quote Post
pmir13
post
Post #4





Grupa: Zarejestrowani
Postów: 282
Pomógł: 89
Dołączył: 12.04.2011

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


Cytat(trueblue @ 15.12.2016, 19:04:54 ) *
Zgadza się, że są dla różnych czujników, ale nie wiem na jakiej podstawie wnioskujesz, że każdy czujnik ma dane z innych dni.
Z tego co napisał autor, każdy czujnik ma najświeższe dane (zbiera co minutę).

Na podstawie pierwszego postu i szacowanych ilości rekordów. Mamy 11 tabel, osobno dla każdego czujnika, w każdej co minutę insert od maja (jak inaczej wytłumaczyć 250k rekordów na tabelę?), szukamy dla każdego czujnika najwyższej i najniższej wartości dla danego dnia. O ile znalezienie tych wartości dla jednej tabeli daje autorowi w tej chwili akceptowalny czas wykonania, to gdy trzeba to powtórzyć dla wszystkich tabel spowolnienie jest już wyraźne. Myślę, że problem przedstawiony jest wystarczająco precyzyjnie.

To że czujnik ma najświeższe dane nic nie zmienia, jeśli chcemy najwyższą temperaturę dzisiaj, nie interesuje nas wpis z letnich upałów.

Dodanie dodatkowej kolumny na datę jest tutaj najbardziej oczywistym krokiem, jednorazowy update na dotychczasowe dane, trigger after insert na wyciągnięcie i zapisanie samej daty (być może również after update o ile robimy update oprócz insertów) plus dwukolumnowy indeks na (date,value) i mamy problem z głowy. Rozwiązanie bez grzebania w aplikacji zbierającej odczyty, opierające się wyłącznie na samej bazie danych (skoro autor może dodawać indeksy to ma do niej dostęp) i niezależne od wielkości bazy, bo dodatkowe czynności przy insertach co minutę nie wpłyną w zauważalny sposób na pracę bazy, a potrzebne do wyświetlenia na stronie dane dostajemy natychmiast z indeksu.
Go to the top of the page
+Quote Post

Posty w temacie
- wachcio   Optymalizacja bazy danych   14.12.2016, 20:49:16
- - trueblue   A jak często wybierasz rekordy z "dziś" ...   14.12.2016, 20:52:42
- - wachcio   Przy każdorazowym uruchomieniu strony. W celach te...   14.12.2016, 21:13:53
- - trueblue   Usuń CURDATE(), a podstaw tam datę z php (date(...   14.12.2016, 21:16:35
- - wachcio   Niestety czas wykonania skryptu bez zmian   14.12.2016, 21:34:41
- - trueblue   1. Możesz zapisywać wszystkie w jednej tabeli? Pew...   14.12.2016, 21:46:38
- - wachcio   Ad. 1 Niestety nie gdyż jest to kopia danych oprog...   14.12.2016, 21:55:57
- - trueblue   ad.2 Partycjonowanie jest opisane w dokumentacji, ...   14.12.2016, 22:24:27
- - wachcio   Czyli dużo kombinacji a efektu może nie być za wie...   14.12.2016, 22:58:59
- - trueblue   Dlaczego nie za wiele? Odczyt z małej tabeli czy z...   14.12.2016, 23:04:12
- - wachcio   Dane są dopisywane do tabel co minuta więc jeśli d...   14.12.2016, 23:13:09
|- - trueblue   Cytat(wachcio @ 14.12.2016, 23:13:09 ...   15.12.2016, 08:40:46
- - viking   W jaki sposób założyłeś indeksy? Mają być dokładni...   15.12.2016, 05:51:29
- - wachcio   Indeksy zakładałem klikając w phpMyAdmin. Pojedync...   15.12.2016, 06:07:34
- - viking   Nie chodzi mi w jakim narzędziu tylko czy faktyczn...   15.12.2016, 06:17:47
- - pmir13   Z tego co autor napisał wynika, że tabele są dla r...   15.12.2016, 09:51:10
|- - trueblue   Cytat(pmir13 @ 15.12.2016, 09:51:10 )...   15.12.2016, 18:04:54
|- - pmir13   Cytat(trueblue @ 15.12.2016, 19:04:54...   15.12.2016, 19:19:46
- - trueblue   Przeoczyłem fakt, że autor potrzebuje również najw...   15.12.2016, 19:33:58
- - wachcio   Kolega pmir13 bardzo dobrze zrozumiał co miałem na...   16.12.2016, 21:39:19
- - pmir13   Dla każdej tabeli: [SQL] pobierz, plaintext UPDATE...   17.12.2016, 06:11:53
- - wachcio   Dziękuję bardzo za pomoc. Po tych zmianach strona ...   17.12.2016, 18:07:16


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: 28.09.2025 - 04:54