Вижте попълване на база данни в ръководството за 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 за бързо тестване.