Viz naplnění databáze v příručce PostgreSQL, depeszův vynikající článek na toto téma a tato otázka SO.
(Všimněte si, že tato odpověď se týká hromadného načítání dat do existující DB nebo vytvoření nové. Pokud máte zájem o obnovení výkonu DB pomocí pg_restore
nebo psql
spuštění pg_dump
výstup, mnoho z toho neplatí od pg_dump
a pg_restore
již dělá věci, jako je vytváření spouštěčů a indexů po dokončení obnovy schématu a dat) .
Je toho hodně co udělat. Ideálním řešením by bylo importovat do UNLOGGED
tabulku bez indexů, poté ji změňte na logovanou a přidejte indexy. Bohužel v PostgreSQL 9.4 není žádná podpora pro změny tabulek z UNLOGGED
do přihlášeného. 9.5 přidává ALTER TABLE ... SET LOGGED
abyste to mohli udělat.
Pokud můžete databázi převést do režimu offline pro hromadný import, použijte pg_bulkload
.
Jinak:
-
Deaktivujte všechny spouštěče na stole
-
Před zahájením importu zrušte indexy a poté je znovu vytvořte. (Trvá to hodně méně času na vytvoření indexu v jednom průchodu než na postupné přidávání stejných dat do něj a výsledný index je mnohem kompaktnější).
-
Pokud provádíte import v rámci jedné transakce, je bezpečné před potvrzením zrušit omezení cizího klíče, provést import a znovu vytvořit omezení. Nedělejte to, pokud je import rozdělen mezi více transakcí, protože byste mohli vnést neplatná data.
-
Pokud je to možné, použijte
COPY
místoINSERT
s -
Pokud nemůžete použít
COPY
zvažte použitíINSERT
s více hodnotami je-li praktické. Zdá se, že to už děláš. Nepokoušejte se uvést také mnoho hodnot v jednomVALUES
ačkoli; tyto hodnoty se musí několikrát vejít do paměti, takže to udržujte na několika stovkách na příkaz. -
Dávkujte své vložky do explicitních transakcí a proveďte stovky tisíc nebo miliony vložení na transakci. Neexistuje žádný praktický limit AFAIK, ale dávkování vám umožní zotavit se z chyby označením začátku každé dávky ve vstupních datech. Opět se zdá, že to již děláte.
-
Použijte
synchronous_commit=off
a obrovskýcommit_delay
snížit náklady na fsync(). To však příliš nepomůže, pokud svou práci spojíte do velkých transakcí. -
INSERT
neboKOPÍROVAT
paralelně z několika spojení. Kolik závisí na diskovém subsystému vašeho hardwaru; v zásadě chcete jedno připojení na fyzický pevný disk, pokud používáte přímo připojené úložiště. -
Nastavte vysokou hodnotu
max_wal_size
hodnota (kontrolní_segmenty
ve starších verzích) a povoltelog_checkpoints
. Podívejte se na záznamy PostgreSQL a ujistěte se, že si nestěžuje na příliš časté kontrolní body. -
Pokud a pouze v případě, že vám nebude vadit ztráta celého clusteru PostgreSQL (databáze a všech ostatních ve stejném clusteru) kvůli katastrofálnímu poškození, pokud systém během importu spadne, můžete zastavit Pg a nastavit
fsync=off , spusťte Pg, proveďte import, pak (životně) zastavte Pg a nastavte
fsync=on
znovu. Viz konfigurace WAL. Nedělejte to, pokud již nějaká data, která vás zajímají, v jakékoli databázi ve vaší instalaci PostgreSQL jsou. Pokud nastavítefsync=off
můžete také nastavitfull_page_writes=off
; znovu, nezapomeňte jej po importu znovu zapnout, abyste zabránili poškození databáze a ztrátě dat. Viz neodolná nastavení v příručce Pg.
Měli byste se také podívat na vyladění systému:
-
Použijte dobrou kvalitu SSD pro ukládání co nejvíce. Dobré disky SSD se spolehlivými, výkonově chráněnými mezipaměti zpětného zápisu neuvěřitelně zrychlují rychlost odevzdání. Jsou méně výhodné, když se budete řídit výše uvedenými radami – což snižuje vyprázdnění disku / počet
fsync()
s - ale stále může být velkou pomocí. Nepoužívejte levné SSD bez řádné ochrany proti výpadku napájení, pokud se nestaráte o uchování svých dat. -
Pokud pro přímo připojené úložiště používáte RAID 5 nebo RAID 6, přestaňte. Zálohujte svá data, restrukturalizujte pole RAID na RAID 10 a zkuste to znovu. RAID 5/6 jsou beznadějné pro výkon hromadného zápisu – i když dobrý řadič RAID s velkou mezipamětí může pomoci.
-
Pokud máte možnost použít hardwarový řadič RAID s velkou mezipamětí pro zpětný zápis zálohovanou baterií, může to skutečně zlepšit výkon zápisu pro pracovní zátěže se spoustou potvrzení. Nepomůže tolik, pokud používáte asynchronní potvrzení s commit_delay nebo pokud během hromadného načítání provádíte méně velkých transakcí.
-
Pokud je to možné, uložte WAL (
pg_wal
nebopg_xlog
ve starých verzích) na samostatném disku / diskovém poli. Nemá smysl používat samostatný souborový systém na stejném disku. Lidé se často rozhodnou použít pro WAL pár RAID1. Opět to má větší vliv na systémy s vysokou mírou potvrzování a má to malý vliv, pokud jako cíl zatížení dat používáte nezaprotokolovanou tabulku.
Také by vás mohla zajímat Optimalizace PostgreSQL pro rychlé testování.