Sortowanie po własnej metodzie, wydajność i cache

Uczę się Railsów. Coś zrobiłem i niby działa, ale wg mnie za wolno i chyba nie nadaje się to do niczego z tego powodu.

Jest model Image i model Vote. Można oddać na każdy obrazek głos dodatni lub ujemny. Polega to na stworzeniu rekordu (wiersza) w tabeli votes. Ten Vote może mieć wartość dodatnią lub ujemną (czyli jest jeden uniwersalny Vote, a nie na przykład VoteDodatni i VoteUjemny).

Czyli żeby wiedzieć ile dany obrazek zebrał punktów, to trzeba wyszukać które votes mają id tego obrazka i zliczać punkty z tych głosów (dodatni to +1, ujemny to -1). Metoda licząca punkty jest w klasie Image, zgodnie z zasadą, że logika ma być w modelu. W widoku jest tylko wywołanie tej metody dla danego |image|.

Dodałem do tego will_paginate i udało mi się jeszcze dodać widoki sortujące obrazki wg punktów.

Zrobiłem 1600 obrazków i okazało się, że zmiana strony trwa ponad 2 sekundy. To znaczy tyle trwa przełączenie na sortowanie po punktach i potem zmienianie stron (next, previous itd. z will_paginate) w tym widoku. Widok z sortowaniem po id czy innych kolumnach działa chyba tak samo szybko jak by obrazków było 10.

Wiem, że jest taka zasada, że szybkość można zwiększyć albo zwiększeniem szybkości CPU albo zwiększeniem pamięci. Gdybym dodał kolumnę z punktami do Image i ją aktualizował za każdym razem, gdy ktoś stworzy nowy, to by śmigało. Ale wiem, że jest też zasada niepowtarzania danych w bazie danych w celu uniknięcia niespójności. To jak się profesjonalnie rozwiązuje taki dylemat? Jakieś opcjonalne cache pewnie, ale jak? W pamięci, w jakimś pliku, dodatkowej tabeli? Może całkiem coś innego (nie wiem, jakieś skrypty po stronie clienta)?

1 Like

Ta zasada nie obowiązuje w momencie przekroczenia murów akademickich ;). Najbardziej oczywistym i jak najbardziej dobrym rozwiązaniem jest dodatkowy atrybut w modelu Image, trzymający aktualni bilans +/-.

1 Like

Jestem tego samego zdania, w dodatku same railsy oferuja coś jak dublowanie COUNTa np counter_cache, także jak dodasz kolumnę, która będzie przechowywać bilans głosów to będzie to jak najbardziej poprawne.

1 Like

Tak, wiem, dodałem tę kolumnę do zliczania całkowitej ilości głosów (było o tym w guides i jak szukałem w necie rails + cache). Wtedy właśnie zacząłem się zastanawiać jak robi się te bazy danych w praktyce, a nie tylko w teorii.