it-swarm.dev

PostgreSQL: Wymuś dane do pamięci

Czy istnieje systematyczny sposób, aby zmusić PostgreSQL do załadowania określonej tabeli do pamięci lub przynajmniej odczytania jej z dysku, aby system mógł ją buforować?

34
Adam Matan

Możesz być zainteresowany jednym z tematów list dyskusyjnych , na co odpowiada Tom Lane (główny programista):

[..] Ale moim zdaniem ludzie, którzy myślą, że są mądrzejsi niż algorytm buforowania LRU, zwykle się mylą. Jeśli stół jest bardzo intensywnie używany, na pewno pozostanie w pamięci. Jeśli zgodnie z algorytmem LRU nie jest wystarczająco mocno wykorzystywany do pozostawania w pamięci, być może przestrzeń pamięci naprawdę powinna zostać wydana na coś innego. [..]

Może Cię również zainteresować pytanie SO pytanie: https://stackoverflow.com/questions/486154/postgresql-temporary-tables i może bardziej odpowiedni https://stackoverflow.com/questions/407006/need-to-load-the-whole-postgresql-database-into-the-ram

27
DrColossos

Postgres 9.4 w końcu dodał rozszerzenie do wstępnego ładowania danych ze relacji do systemu operacyjnego lub bufora bufora bazy danych (do wyboru):

pg_prewarm

Pozwala to szybciej osiągnąć pełną wydajność operacyjną.

Uruchom raz w bazie danych (szczegółowe instrukcje tutaj ):

CREATE EXTENSION pg_prewarm;

Następnie łatwo jest wstępnie załadować dowolną relację. Podstawowy przykład:

SELECT pg_prewarm('my_tbl');

Znajduje pierwszą tabelę o nazwie my_tbl w ścieżce wyszukiwania i ładuje ją do bufora bufora Postgres

Lub:

SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');

prefetch wydaje asynchroniczne żądania pobierania wstępnego do systemu operacyjnego, jeśli jest to obsługiwane, lub w przeciwnym razie zgłasza błąd. read odczytuje żądany zakres bloków; w przeciwieństwie do prefetch, jest to synchroniczne i obsługiwane na wszystkich platformach i kompilacjach, ale może być wolniejsze. buffer odczytuje żądany zakres bloków do bufora bufora bazy danych.

Wartość domyślna to buffer, która ma największy wpływ (wyższy koszt, najlepszy efekt).

Aby uzyskać więcej informacji, przeczytaj instrukcję , cytaty są stamtąd.
Depesz blogował też o tym.

39

W ogólnym przypadku, jeśli masz wystarczająco dużo RAM), ogólnie możesz zaufać usłudze bazy danych, aby dobrze wykonywać czynności, których regularnie używasz w pamięci RAM. Niektóre systemy pozwalają ci zasugerować, że tabela powinna zawsze trzymaj w RAM (co jest przydatne w przypadku małych tabel, które nie są często używane, ale kiedy są używane, ważne jest, aby odpowiadały tak szybko, jak to możliwe)), ale jeśli pgsql ma taką tabelę, podpowie ci musisz bardzo uważać na ich użycie, ponieważ zmniejszasz ilość dostępnej pamięci do buforowania czegokolwiek innego, aby ogólnie spowolnić działanie aplikacji.

Jeśli chcesz uruchomić pamięć podręczną strony bazy danych podczas uruchamiania (na przykład po ponownym uruchomieniu lub innej operacji konserwacji, która powoduje, że DB zapomina o wszystkim, co jest buforowane), to napisz skrypt, który wykonuje następujące czynności:

SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>

(ten ostatni krok powtarza się dla każdego indeksu lub kursu i uważaj, aby pola w klauzuli ORDER BY były w odpowiedniej kolejności)

Po uruchomieniu powyższego każda strona danych i indeksu powinna zostać przeczytana, więc będzie w pamięci podręcznej RAM (przynajmniej na razie)). Mamy takie skrypty dla naszych baz danych aplikacji, które są uruchamiane po ponownym uruchomieniu, aby pierwsi użytkownicy logujący się później do systemu nie odczuwali wolniejszego reagowania. Lepiej jest pisać odręcznie dowolny taki skrypt, zamiast skanować tabele definicji db (np. sys.objects/sys.indexes/sys.columns w MSSQL), możesz następnie selektywnie skanować najczęściej używane indeksy zamiast skanować wszystko, co potrwa dłużej.

4
David Spillett

Miałem podobny problem:
Po zrestartowaniu usługi serwera i porzuceniu wszystkich danych kasowanych, wiele zapytań wywoływanych po raz pierwszy było naprawdę bardzo powolnych, ze względu na specyficzną złożoność zapytań, do momentu wykonania wszystkich niezbędnych indeksów i danych. oznacza to na przykład, że użytkownicy muszą trafić raz „każdy element” (czas wykonania 1-3 sekund) i powiązane dane z 50 milionów wierszy, aby użytkownicy nie doświadczyli już żadnych niepożądanych opóźnień. Pierwsze irytujące zawieszanie się zajmuje użytkownikom pierwsze 3 godziny, aż większość używanych danych zostanie spieniężona, a programy rujnują wydajność na najwyższym poziomie, a nawet koniec, 2 dni kilka nagłych krótkich opóźnień, gdy uderzają mniej danych za pierwszym razem ... , dla danych statystycznych itp.

Aby rozwiązać ten problem, napisałem mały skrypt python skrypt, który wykonuje selekcje na najcięższych używanych tabelach z dużymi indeksami. Uruchomienie zajęło 15 minut i nie opóźniało wydajności.

1
LongBeard_Boldy

Używam RamDrive z QSoft, który był testowany jako najszybszy ramdysk dla Windows. Właśnie użyłem

initdb -D e:\data

gdzie e:\jest miejscem RamDisk.

0
David

Hmmm, może pomóc polecenie COPY. Wystarczy wykonać KOPIUJ, aby przejść do standardowego wyjścia i odczytać z niego. Można to zrobić za pomocą pg_dump:

pg_dump -U <user> -t <table> <database> > /dev/null

Innym sposobem jest znalezienie wszystkich plików tabel i uruchomienie cat <files> > /dev/null.

Oto przykład, jak uzyskać nazwy plików tabel:

# SELECT oid, datname FROM pg_database ;
  oid  |  datname  
-------+-----------                                                                                                                                          
<...>
 16384 | test
-- out of database is 16384
# SELECT oid, relname FROM pg_class WHERE relname like 'fn%';
  oid  | relname 
-------+---------
 24576 | fn
(1 row)
-- oid of our table is 24576

więc plik (i) tabeli to/path/to/pgsql/data/base/16384/24576 *

Możesz także chcieć czytać indeksy i tosty, a także pobierać ich Oids w ten sam sposób.

BTW, dlaczego go potrzebujesz? Uważam, że postgresql i system operacyjny są wystarczająco inteligentne, aby buforować najgorętsze dane i utrzymywać dobrą jakość. wydajność pamięci podręcznej.

0
rvs