Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Dużo drobnych danych - jak optymalizować
strateg
post 10.09.2014, 18:08:17
Post #1





Grupa: Zarejestrowani
Postów: 9
Pomógł: 1
Dołączył: 23.12.2010

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


Cześć wszystkim,

Mój dzisiejszy problem jest dość nietypowy. Chciałem zrealizować system statystyk. Dla każdego użytkownika systemu byłaby generowana jedna liczba określająca postęp w danym dniu i wpisywana do bazy danych. Wpis miałby postać:

id_user | date | points

Chciałbym docelowo przechowywać statystyki z miesiąca, a najlepiej roku. Problemy zaczynają się, gdy zaczniemy liczyć. Załóżmy, że portal ma 10 tysięcy użytkowników. Wtedy statystyki obejmujące tylko miesiąc (starsze automatycznie kasujemy) zajmują:

100k * 30 = 3 miliony rekordów - bardzo dużo!

PROBLEM
Dopuszczam możliwość, że użytkowników może być znacznie więcej, albo okres przechowywania może być dłuższy. W obu przypadkach uzyskuję bazę danych, w których mam dużo rekordów przechowujących mało informacji. Wnioskuję, że wydajność tak błahego rozwiązanie będzie okropna.

OPTYMALIZACJA 1
Przechowuję dane tygodniami, czyli mam rekord zawierający łącznie zapis z 7 ostatnich dni. Wtedy znacząco zmniejszam ilość rekordów, komplikuję jednak pobieranie i wstawianie danych, które robią się nieoczywiste. Opcji z miesięcznym rekordem (30 pól) nawet nie biorę pod uwagę.

OPTYMALIZACJA 2
Kompresuję dane do formatu JSON i w ten sposób dla każdego rekordu przechowuję dowolną ilość dni. Rozmiar takich danych nie jest tragiczny, a ilość rekordów jest już minimalna. Pobieranie - żaden problem. Modyfikacja będzie wymagała aktualizacji przynajmniej 1/24 rekordów (robię to dla każdej strefy czasowej). Wtedy mogę użyć jakieś "inteligentnego JOINA" z operacją na łańcuchach i pośrednio zaleczyć problem. Usuwanie starych dni jest jednak problematyczne: muszę wczytywać osobno każdy rekord, modyfikować go w skrypcie i odsyłać - masakra.

OPTYMALIZACJA 3
Podobny sposób, jak w wersji 2, jednak w danym rekordzie pilnuję, aby była informacja tylko o konkretnej ilości dni (np. miesiąc). Wtedy w razie potrzeby pobieram odpowiednią ilość rekordów (max 2 dla okresu miesięcznego) i jest fajnie. Regularnie usuwam rekordy ze zbyt starą informacją (starsze niż miesiąc). Oczywiście 30 dni można zamienić na dowolną ilość dni.

PODSUMOWANIE
CO o tym sądzicie? Macie jakieś lepsze pomysły/metody? Jak realizujecie takie problemy?

Pozdrawiam,
Marcin

Ten post edytował strateg 10.09.2014, 19:45:58
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 6)
Pyton_000
post 10.09.2014, 19:30:31
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


3mln rekordów twojego typu to nie jest dużo, tym bardziej że rozmiar pojedynczego rekordu oszacujemy na ok 24 bajty + rozmiar klucza czyli ok 32 bajty. Pikuś.

Zrób sobie taką tabelkę dla testów i zobaczysz jak wydajność będzie się trzymać.


Raczej sugerowałbym zostanie przy 1 rekord - 1 wpis.
Możesz zastosować partycjonowanie tabeli po ID użytkownika (zakres np. 1tyś użytkowników/partycja), dzięki czemu uzyskasz "mniejsze" tabelki i gigantyczny wzrost wydajności przy przeszukiwania dla konkretnego użytkownika, bo wtedy silnik bierze konkretną partycję i szuka tylko w 1 tyś użytkowników.
Go to the top of the page
+Quote Post
strateg
post 10.09.2014, 19:40:07
Post #3





Grupa: Zarejestrowani
Postów: 9
Pomógł: 1
Dołączył: 23.12.2010

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


Czyli jednak najprostsze rozwiązania są najlepsze. Nie ukrywam, że dla mnie takie rozwiązanie byłoby oczywiście preferowane. A co jeśli będę miał znacznie więcej danych, powiedzmy 50 milionów rekordów (myślę o rocznej żywotności statystyk i większej ilości użytkowników). Wtedy dalej ma to sens?

Oczywiście klucz nakładam na id_użytkownika, tylko po nim przeszukuję wpisy. Następna kwestia to partycjonowanie. Czy pomimo obecność klucza, powinienem je wykonywać?

Ten post edytował strateg 10.09.2014, 19:46:45
Go to the top of the page
+Quote Post
Pyton_000
post 10.09.2014, 19:49:13
Post #4





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Tu możesz poczytać o partycjonowaniu

http://db-diary.blogspot.com/2014/08/party...-mysql-v55.html
Go to the top of the page
+Quote Post
strateg
post 10.09.2014, 19:57:28
Post #5





Grupa: Zarejestrowani
Postów: 9
Pomógł: 1
Dołączył: 23.12.2010

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


OK, bardzo dziękuję za link, już się biorę do lektury. Po prostu tak wielkie liczby trochę mnie przerażają, a tu jednak nie ma czego się bać ;p Jak dojdę do jakichś wnioskó - oczywiście napiszę.
Go to the top of the page
+Quote Post
Pyton_000
post 10.09.2014, 20:05:22
Post #6





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Najlepszą metodą jest przetestowanie namacalnie takich rzeczy.
Ostatnio pisząc co nie co w Laravel trafiłem na fajna bibliotekę co się zowie Faker do generowania danych.
https://github.com/fzaninotto/Faker
Go to the top of the page
+Quote Post
strateg
post 10.09.2014, 20:26:19
Post #7





Grupa: Zarejestrowani
Postów: 9
Pomógł: 1
Dołączył: 23.12.2010

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


Dzięki, że dałeś mi do zrozumienia, że JSON nie jest najlepszym pomysłem. Trochę byłoby męczenia się z nim, a to wszystko w sumie niepotrzebne wink.gif
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 04:28