Jaki współczynnik wypełnienia tabeli buforowania?


10

Mam mocno zaktualizowaną / dostępną tabelę, w której przechowuję zserializowane obiekty Java. Są w tabeli przez 2-3 godziny (są również aktualizowane w tym okresie), a następnie usuwane. Rozmiar stołu to około 300 MB. Zauważyłem, że jest to bardzo, bardzo często VACUUMed i zastanawiam się, czy zmiana fillfactorpomogłaby?

Odpowiedzi:


17

Kluczowe słowa tutaj to:

  1. „mocno zaktualizowany”
  2. „w tabeli na 2-3 godziny”.

Punkt 1. wskazuje na niższy współczynnik wypełnienia, a 2. jest odwrotnie. Poprawia wydajność, jeśli wiele wersji wierszy jest przechowywanych na tej samej stronie danych. GORĄCE aktualizacje by to osiągnęły. Przeczytaj tutaj lub tutaj . Potrzebują trochę miejsca na stronie danych - na przykład martwych krotek lub miejsca zarezerwowanego przez fillfactor<100. Ale mogą to zrobić tylko wtedy, gdy żaden indeks nie obejmuje żadnej ze zaktualizowanych kolumn , co powinno być prawdziwe w twoim przypadku.

Innym ważnym czynnikiem byłby krotek (w porównaniu z wielkością strony (najczęściej 8 kb). Więcej szczegółów w tej pokrewnej odpowiedzi:

Jeśli rozmiar krotki wynosi 4 kb lub więcej, zmniejszenie współczynnika wypełnienia byłoby daremne, ponieważ na stronie danych nigdy nie może być więcej niż jedna krotka. Równie dobrze możesz zostawić to w 100(co i tak jest domyślne). Jednak niektóre typy danych są „opiekane” i przechowywane poza linią, jeśli przekraczają limit rozmiaru, więc krotki wymagające takiej ilości w głównym rozwidleniu relacji są rzadkie.

Cokolwiek zrobisz, VACUUM będzie uruchamiane często. I to na ogół dobra rzecz, nie martwiłbym się tym. Tworzysz wiele martwych krotek. VACUUMidentyfikuje martwe wiersze, które nie są już widoczne dla żadnej otwartej transakcji. Instrukcja:

Standardowa forma VACUUMusuwania martwych wierszy w tabelach i indeksach oraz oznacza miejsce dostępne do ponownego użycia w przyszłości .

Odważny nacisk moje.
Możesz grać z ustawieniami dla poszczególnych tabel dla autovacuum, aby wyzwalać go rzadziej (lub więcej) tylko dla tego stołu:

Domyślne progi i współczynniki skalowania są pobierane postgresql.conf, ale można je zastąpić dla poszczególnych tabel ;

Odważny nacisk moje. W szczególności z autovacuum_vacuum_thresholdiautovacuum_vacuum_scale_factor . VACUUMDużo biegania może być dobrym pomysłem, a nie bardzo niskim fillfacter. To zależy od wzorców dostępu. Jeśli wszystkie krotki będą działać, powiedzmy, 3 godziny, a każda z nich zostanie kilkakrotnie zaktualizowana, nadal obniżę liczbę fillfactordo około 50. Musisz przetestować i znaleźć najsłodsze miejsce.

Alternatywy

Wszystko to na bok, ponieważ twoje dane wydają się niestabilne na początek: użyj UNLOGGEDtabeli :

Dane zapisane w niezalogowanych tabelach nie są zapisywane w dzienniku z wyprzedzeniem zapisu (patrz rozdział 29 ), co czyni je znacznie szybszymi niż zwykłe tabele. Nie są one jednak odporne na awarie : niezalogowany stół jest automatycznie obcinany po awarii lub nieczystym zamknięciu. Zawartość niezalogowanej tabeli również nie jest replikowana na serwerach rezerwowych.

Odważny nacisk moje. Nie używaj tego, jeśli twój serwer może ulec awarii i nadal potrzebujesz danych. Ale jeśli mówimy o danych sesji dla aplikacji internetowych, może to być akceptowalna cena do zapłaty.

Lub jeszcze bardziej radykalny: skorzystaj ze sklepu klucz-wartość, takiego jak Redis, jeśli możesz obejść się bez funkcji i zabezpieczeń zapewnianych przez RDBMS.


Myślę, że UNLOGGED jest dokładnie tym, czego potrzebuję
Michał

0

Sugerowałbym DBMS o kluczowej wartości, ale wyrzucam to ze względu na zainteresowanie.

Zamiast wykonywania instrukcji INSERT & DELETE wykonuj tylko UPDATE.

Struktura tabeli będzie podobna

ID      integer  -- sequential ID
Used    boolean  -- default FALSE
Object  -- whatever type is appropriate

Kolumna do przechowywania obiektów będzie miała stałą długość, aby uniknąć podziałów i ruchów wierszy. Zmień rozmiar tej kolumny, aby pomieścić obiekty i wydajnie wypełnić stronę na dysku.

Wstępnie wypełnij tabelę tyloma wierszami, ile potrzebujesz i kilkoma innymi.

Kiedy obiekt ma zostać zapisany, znajdź wiersz z Used = False i UPDATE tego wiersza. Kiedy obiekt ma zostać zniszczony, ustaw opcję „Fałsz”. Nie ma żadnych śmieci, a zatem nie można ich usuwać.

Oczywiście istnieje wiele, wiele warunków wyjątków do obsłużenia (przepełnienie wiersza, przepełnienie tabeli, warunki wyścigu przy użyciu identyfikatora itp.), Ale żaden nie jest nie do pokonania.


O ile rozumiem, te aktualizacje zwykle nadal zapisują całą nową kopię wiersza na dysk, chyba że jest to GORĄCA aktualizacja. Więc z czasem nadal potrzebujesz GC / Odkurzania.
Jeff Widman,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.