sql >> Databáze >  >> RDS >> PostgreSQL

Jak zrychlit výkon vkládání v PostgreSQL

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ísto INSERT 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 jednom VALUES 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 nebo KOPÍ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 povolte log_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íte fsync=off můžete také nastavit full_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 nebo pg_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í.



  1. Úplný seznam znakových sad podporovaných MariaDB

  2. Jak vytvořit skutečný vztah jeden k jednomu na serveru SQL Server

  3. Získávání zadaných výsledků z ActiveRecord raw SQL

  4. Jak získat sloupec primárního klíče v Oracle?