Jakie są najlepsze praktyki buforowania stronicowanych wyników, których kolejność / właściwości mogą ulec zmianie?

11

Jakie są najlepsze praktyki buforowania stronicowanych wyników wyszukiwania, których kolejność / właściwości można zmienić?

Powiedzmy, że w mojej aplikacji ktoś chce zobaczyć ostatnie 20 wątków dyskusji (z 10 000). Do bazy danych zostanie wysłane żądanie servletpobrania pierwszych 20 rekordów z tabeli wątków dyskusji jako XML / JSON. Jeśli następnie chcą zobaczyć następne 20, przechodzą do następnej strony wyników, co odpala kolejne żądanie uzyskania następnej partii (limit i offset = 20 itd.).

Aby zmniejszyć obciążenie serwera i oczekiwania klientów, chciałbym buforować poprzednie strony wyników. Mam jednak dwa pytania:

  1. Tabela, w której pokazane są wyniki, może być uporządkowana według więcej niż jednego atrybutu (tj. Data utworzenia wątku, autor wątku, data ostatniego postu). Oznacza to, że stwierdzenie typu „pierwsze 20 wyników” nie ma sensu bez kontekstu (tj. Przez co zamawiamy). W jaki sposób front-end komunikuje się z back-endem o tym, co już załadował? Moją pierwszą myślą było użycie identyfikatorów dla każdego wyniku, ale odesłanie ich z powrotem do serwera przy kolejnych żądaniach (i filtrowanie wyników na ich podstawie) byłoby tak samo czasochłonne jak odesłanie wszystkiego na ślepo. Jak mogę to zrobić?
  2. Co się stanie, jeśli zmieni się atrybut wcześniej zwróconego wyniku (tj. Najnowszej daty końcowej)? Następnie potrzebujemy sposobu sprawdzenia każdego wyniku, aby zobaczyć, czy został zmodyfikowany po stronie serwera od czasu, gdy został on umieszczony na stronie. Jak mogę to zrobić?
towary
źródło
Twój przykład jest trochę szorstki. Jeśli to tylko 100 wątków, najlepiej pobrać wszystkie 100 za jednym razem. Jeśli ciągniesz 20 na 10 000, to inna historia.
Dan Pichelman,
@DanPichelman Przepraszamy, byłem trochę niejasny. Będzie to więcej niż 10 000.
towary szybko
Zmieniono numer dla zachowania przejrzystości.
towary szybko
Czy to jest http? Jeśli tak, dlaczego nie po prostu buforować na podstawie adresu URL? Posiadaj wszystkie parametry w adresie URL. Jeśli jest to przeglądarka, spróbuj użyć pamięci podręcznej przeglądarki. Jeśli jest to aplikacja, ustaw wygasanie pamięci podręcznej. Android Volley działa całkiem dobrze.
frostymarvelous

Odpowiedzi:

7

Wygląda na to, czego potrzebujesz, jest opakowaniem dla wszystkich parametrów, które definiują strony (powiedzmy pageNumber, pageSize, sortType, totalCount, itd.) I korzystają z tego DataRequestobiektu jako klucz dla mechanizmu buforowania. Od tego momentu masz wiele opcji obsługi pamięci podręcznej:

  • Zaimplementuj jakiś mechanizm limitu czasu w celu odświeżenia pamięci podręcznej (w zależności od częstotliwości zmian danych).
  • Poproś o detektor, który sprawdza zmiany w bazie danych i aktualizuje pamięć podręczną w oparciu o powyższe parametry.
  • Jeśli zmiany są wykonywane przez ten sam proces, zawsze możesz oznaczyć pamięć podręczną jako przestarzałą przy każdej zmianie i zaznaczyć tę flagę, gdy strona jest żądana.

Pierwsze dwa mogą obejmować mechanizm harmonogramu wyzwalający się w określonych odstępach czasu lub na podstawie zdarzenia. Ostatni może być prostszy, jeśli masz pojedynczy punkt dostępu do danych.

Wreszcie, jak wspomniano @DanPichelman, może szybko stać się zbyt skomplikowanym algorytmem, który przewyższa korzyści, więc upewnij się, że wzrost wydajności uzasadnia złożoność algorytmu.

rae1
źródło
3

Prawdopodobnie poradziłbym sobie z tym w ten sposób:

  1. Traktuj wszystkie porządki jako różne sekwencje razem. Dodatkowa księgowość nie będzie warta śledzenia tego, co ma każdy klient (lub wysyłania go w kółko).
  2. Ilekroć strony użytkownika są wyświetlane natychmiast z pamięci podręcznej, jednocześnie wysyłając GET na serwer, który zawiera hash lub czas ostatniego dostępu. Serwer odsyła pełną stronę tylko wtedy, gdy coś się zmieniło.
  3. Pobierz z serwera więcej niż jedną stronę interfejsu użytkownika na raz. Na przykład, jeśli interfejs użytkownika wyświetla 20 wpisów, zapytanie 60. Muszę to przetestować, ale oczekuję, że najbardziej efektywny rozmiar zwrotu będzie zwykle większy niż średnia ilość danych pokazanych na jednej stronie. Dzięki temu interfejs użytkownika jest bardzo responsywny w przypadku niektórych przewracanych stron.
  4. Pobieranie wstępne kończy się ponownie, gdy zbliżasz się do granicy. Pomaga to zachować szybkie czasy ładowania z pamięci podręcznej.
Chris Pitman
źródło
2

Tylko myśl - w wywołaniu serwera przekaż zwykłe parametry plus tablicę skrótów MD5 reprezentujących aktualnie buforowane poprzednio przeglądane strony danych.

Wezwanie zwrotne zawierałoby wszystkie zwykłe dane dla nowej bieżącej strony, a także aktualizacje dla wszelkich nieaktualnych wcześniej przeglądanych stron. Możesz użyć starego skrótu jako klucza.

Najpierw poleciłbym wiele testów wydajności i czasu - kod po stronie klienta będzie o wiele bardziej skomplikowany, niż gdybyś po prostu uderzył w serwer dla każdej strony danych. Upewnij się, że dodatkowa złożoność powoduje znaczącą poprawę.

Dan Pichelman
źródło
Dziękuję za odpowiedź. Myślałem o mieszaniu, ale nie jestem pewien, czy to pomoże w scenariuszu ponownego zamawiania (tj. Nie jest wystarczająco szczegółowe i działa tylko na stronie, a nie na wynik). Myślę, że twój ostatni akapit jest dobrym punktem i zaczynam myśleć, że złożoność każdego możliwego rozwiązania przeważy korzyści w zakresie wydajności.
towary szybko