it-swarm-eu.dev

PostgreSQL: Přinutí data do paměti

Existuje systematický způsob, jak vynutit PostgreSQL, aby načíst konkrétní tabulku do paměti, nebo ji alespoň načíst z disku, aby ji systém uložil do mezipaměti?

34
Adam Matan

Možná vás zajímá jedno z témata témat adresáře , odpovídá Tom Lane (hlavní dev):

[..] Myslím si však, že lidé, kteří si myslí, že jsou chytřejší než algoritmus ukládání do mezipaměti LRU, se obvykle mýlí. Pokud je stůl velmi těžce používán, zůstane v paměti v pořádku. Pokud není podle algoritmu LRU dostatečně využíván k tomu, aby zůstal v paměti, měl by se paměťový prostor skutečně vynaložit na něco jiného. [..]

Možná vás také zajímá otázka SO: https://stackoverflow.com/questions/486154/postgresql-temporary-tables a možná vhodnější https://stackoverflow.com/questions/407006/need-to-load-the-whole-postgresql-database-into-the-ram

27
DrColossos

Postgres 9.4 konečně přidal rozšíření pro předběžné načtení dat ze vztahů do OS nebo vyrovnávací paměti databáze (podle vašeho výběru):

pg_prewarm

To umožňuje rychlejší dosažení plného provozního výkonu.

Spusťte jednou v databázi (podrobné pokyny zde ):

CREATE EXTENSION pg_prewarm;

Pak je snadné přednastavit jakýkoli daný vztah. Základní příklad:

SELECT pg_prewarm('my_tbl');

Vyhledá první tabulku s názvem my_tbl do vyhledávací cesty a načte ji do vyrovnávací paměti Postgres

Nebo:

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

prefetch vydává operačnímu systému asynchronní žádosti o předběžné načtení, pokud je podporováno, nebo vyvolá chybu jinak. read přečte požadovaný rozsah bloků; na rozdíl od prefetch je to synchronní a podporované na všech platformách a sestavách, ale může to být pomalejší. buffer načte požadovaný rozsah bloků do mezipaměti databáze.

Výchozí hodnota je buffer, která má největší dopad (vyšší náklady, nejlepší efekt).

Přečtěte si příručku pro více informací , citace jsou odtamtud.
Depesz blogged také o tom.

39

V obecném případě, pokud máte dost RAM, můžete obecně věřit databázové službě, aby odvedla dobrou práci s udržováním věcí, které pravidelně používáte v paměti RAM. Některé systémy umožňují naznačit, že by tabulka měla vždy se koná v RAM (což je užitečné pro malé tabulky, které se často nepoužívají, ale když se používají, je důležité, aby reagovaly co nejrychleji), ale pokud pgsql takové tabulky naznačuje, musíte být velmi opatrní při jejich používání, protože snižujete množství paměti dostupné pro ukládání do mezipaměti cokoli jiného, ​​abyste celkově zpomalili svoji aplikaci.

Pokud se chystáte připravit mezipaměť stránky databáze při spuštění (například po restartu nebo jiné údržbě, která způsobí, že DB zapomene všechno, co je uloženo v mezipaměti), napište skript, který provede následující:

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

(poslední krok se opakoval pro každý index nebo kurz a buďte opatrní, aby byla pole v klauzuli ORDER BY ve správném pořadí)

Po spuštění výše by měla být všechna data a indexová stránka přečtena, a tak bude v mezipaměti RAM page cache (prozatím)). Pro naše aplikační databáze máme takové skripty, které se spouští po restartu, takže první uživatelé, kteří se přihlásí do systému, poté nezaznamenají pomalejší odezvu. Raději si ručně píšete jakýkoli takový skript, místo skenování tabulek definic db (jako sys.objects/sys.indexes/sys.columns v MSSQL), pak můžete selektivně prohledávat indexy, které se nejčastěji používají, místo skenování vše, které bude trvat déle.

4
David Spillett

Měl jsem podobný problém:
Po restartování služby serveru a všech proplácených dat kleslo, mnoho dotazů se nazývalo poprvé, když opravdu opravdu pomalé, příčina specifické složitosti dotazů, dokud nebyly všechny potřebné indexy a data proplaceny. to znamená, že například uživatelé musí zasáhnout jednou za každou „položku“ (čas spuštění 1-3 sekundy) a související data z 50 milionů řádků, takže uživatelé už nebudou mít žádné nežádoucí zpoždění. Trvá první 3 hodiny, než uživatelé zažijí nepříjemné zablokování, dokud se nejpoužívanější data proplácejí a programy ničí špičkový výkon s produkcí, končí i poté, 2 dny několik náhlých krátkých zpoždění, když zasáhne méně poprvé přístupná data ... , pro statistické údaje atd.

Chcete-li to vyřešit, napsal malý python skript, který provádí výběry na nejtěžších používaných tabulkách s velkými indexy. Trvalo to 15 minut, aniž by došlo ke zpoždění výkonu.

1
LongBeard_Boldy

Jako nejrychlejší ramdisk pro Windows používám RamDrive od QSoft, což bylo benchmarked . Právě jsem použil

initdb -D e:\data

kde e:\je místo RamDisk.

0
David

Hmmm, může být COPY příkaz by pomohl. Stačí spouštět COPY k vytažení a čtení z toho. Lze to provést pomocí pg_dump:

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

Jiným způsobem je najít všechny soubory tabulky a spustit cat <files> > /dev/null.

Zde je příklad, jak získat názvy názvů tabulek:

# 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

soubor tabulky je tedy/cesta/k/pgsql/data/base/16384/24576 *

Chcete také číst indexy a tabulky toastů, stejně tak získejte jejich oidy.

BTW, proč to potřebujete? Věřím, že postgresql a OS jsou dostatečně chytré, aby vyrovnávaly nejžhavější data a udržovaly dobré výsledky. účinnost mezipaměti.

0
rvs