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