PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да ускорите производителността на вмъкване в PostgreSQL

Вижте попълване на база данни в ръководството за PostgreSQL, отличната статия на depesz, както обикновено по темата, и този въпрос SO.

(Обърнете внимание, че този отговор е за групово зареждане на данни в съществуваща DB или за създаване на нова. Ако се интересувате, възстановете производителността на DB с pg_restore или psql изпълнение на pg_dump изход, голяма част от това не важи след pg_dump и pg_restore вече прави неща като създаване на задействания и индекси, след като завърши възстановяване на схема+данни) .

Има много да се направи. Идеалното решение би било импортирането в UNLOGGED таблица без индекси, след това я променете на регистрирана и добавете индексите. За съжаление в PostgreSQL 9.4 няма поддръжка за промяна на таблици от UNLOGGED да се регистрира. 9.5 добавя ALTER TABLE ... SET LOGGED за да ви позволя да направите това.

Ако можете да изведете базата си данни офлайн за груповото импортиране, използвайте pg_bulkload .

В противен случай:

  • Деактивирайте всички тригери на масата

  • Пуснете индексите преди да започнете импортирането, създайте ги отново след това. (Отнема много по-малко време за изграждане на индекс с едно преминаване, отколкото за постепенно добавяне на едни и същи данни към него и полученият индекс е много по-компактен).

  • Ако извършвате импортиране в рамките на една транзакция, е безопасно да премахнете ограниченията на външния ключ, да извършите импортирането и да създадете отново ограниченията, преди да извършите ангажимент. Не правете това, ако импортирането е разделено на множество транзакции, тъй като може да въведете невалидни данни.

  • Ако е възможно, използвайте COPY вместо INSERT s

  • Ако не можете да използвате COPY помислете за използването на многозначен INSERT ако е практично. Изглежда вече правиш това. Не се опитвайте да изброявате също много стойности в един VALUES все пак; тези стойности трябва да се поберат в паметта няколко пъти, така че задръжте до няколкостотин на израз.

  • Обединете вашите вмъквания в изрични транзакции, правейки стотици хиляди или милиони вмъквания на транзакция. Няма практически ограничение AFAIK, но пакетирането ще ви позволи да се възстановите от грешка, като маркирате началото на всяка партида във вашите входни данни. Отново изглежда, че вече правите това.

  • Използвайте synchronous_commit=off и огромно commit_delay за намаляване на разходите за fsync(). Това обаче няма да помогне много, ако сте обединили работата си в големи транзакции.

  • INSERT или COPY паралелно от няколко връзки. Колко зависи от дисковата подсистема на вашия хардуер; като правило, искате една връзка на физически твърд диск, ако използвате директно свързано съхранение.

  • Задайте висок max_wal_size стойност (checkpoint_segments в по-стари версии) и активирайте log_checkpoints . Разгледайте регистрационните файлове на PostgreSQL и се уверете, че не се оплакват от контролни точки, които се появяват твърде често.

  • Ако и само ако нямате нищо против да загубите целия си PostgreSQL клъстер (вашата база данни и всички други в същия клъстер) поради катастрофална повреда, ако системата се срине по време на импортирането, можете да спрете Pg, задайте fsync=off , стартирайте Pg, направете своя импорт, след което (жизнено) спрете Pg и задайте fsync=on отново. Вижте конфигурация на WAL. Не правете това, ако вече има данни, които ви интересуват, в която и да е база данни във вашата инсталация на PostgreSQL. Ако зададете fsync=off можете също да зададете full_page_writes=off; отново, просто не забравяйте да го включите отново след импортирането, за да предотвратите повреда на базата данни и загуба на данни. Вижте нетрайните настройки в ръководството за Pg.

Трябва също да разгледате настройката на вашата система:

  • Използвайте добро качество SSD дискове за съхранение колкото е възможно повече. Добрите SSD дискове с надеждни, защитени от захранване кешове за обратно запис правят скоростта на записване невероятно по-бърза. Те са по-малко полезни, когато следвате съветите по-горе - което намалява изчистването на диска / броя на fsync() s - но все още може да бъде голяма помощ. Не използвайте евтини SSD дискове без подходяща защита от прекъсване на захранването, освен ако не ви е грижа за съхраняването на вашите данни.

  • Ако използвате RAID 5 или RAID 6 за директно свързано съхранение, спрете сега. Архивирайте данните си, преструктурирайте своя RAID масив до RAID 10 и опитайте отново. RAID 5/6 са безнадеждни за производителност при групово записване - въпреки че един добър RAID контролер с голям кеш може да помогне.

  • Ако имате възможност да използвате хардуерен RAID контролер с голям кеш за обратно запис с батерии, това наистина може да подобри производителността на запис за натоварвания с много ангажименти. Това не помага толкова много, ако използвате асинхронно записване с commit_delay или ако правите по-малко големи транзакции по време на групово зареждане.

  • Ако е възможно, съхранявайте WAL (pg_wal или pg_xlog в стари версии) на отделен диск / дисков масив. Няма смисъл да използвате отделна файлова система на същия диск. Хората често избират да използват двойка RAID1 за WAL. Отново, това има по-голям ефект върху системи с висока честота на записване и има малък ефект, ако използвате нерегистрирана таблица като цел за зареждане на данни.

Може също да се интересувате от Оптимизиране на PostgreSQL за бързо тестване.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Мониторинг на PostgreSQL в хибридна среда

  2. По-добре ли е да създадете индекс, преди да попълните таблица с данни, или след като данните са на мястото си?

  3. Използване на регулярен израз в WHERE в Postgres

  4. Как работи функцията CONCAT() в PostgreSQL

  5. Конфигурационен параметър work_mem в PostgreSQL на Linux