sql >> Database teknologi >  >> RDS >> PostgreSQL

Sådan fremskyndes indsættelsesydelsen i PostgreSQL

Se udfylde en database i PostgreSQL-manualen, depesz's excellent-as-usual-artikel om emnet, og dette SO-spørgsmål.

(Bemærk, at dette svar handler om at masseindlæse data i en eksisterende DB eller oprette en ny. Hvis du er interesseret, gendan DB ydeevne med pg_restore eller psql udførelse af pg_dump output, meget af dette gælder ikke siden pg_dump og pg_restore allerede gør ting som at oprette triggere og indekser, efter at den er færdig med en skema+datagendannelse) .

Der er meget, der skal gøres. Den ideelle løsning ville være at importere til en UNLOGGED tabel uden indekser, så skift den til logget og tilføj indekserne. Desværre i PostgreSQL 9.4 er der ingen understøttelse for at ændre tabeller fra UNLOGGED til logget. 9.5 tilføjer ALTER TABLE ... SET LOGGED for at tillade dig at gøre dette.

Hvis du kan tage din database offline til masseimporten, skal du bruge pg_bulkload .

Ellers:

  • Deaktiver eventuelle udløsere på bordet

  • Drop indekser, før du starter importen, genskab dem bagefter. (Det kræver meget mindre tid til at bygge et indeks på én gang, end det gør til at tilføje de samme data til det gradvist, og det resulterende indeks er meget mere kompakt).

  • Hvis du udfører importen inden for en enkelt transaktion, er det sikkert at droppe begrænsninger for fremmednøgle, udføre importen og genskabe begrænsningerne, før du forpligter dig. Gør ikke dette, hvis importen er opdelt på tværs af flere transaktioner, da du muligvis introducerer ugyldige data.

  • Hvis det er muligt, brug COPY i stedet for INSERT s

  • Hvis du ikke kan bruge COPY overvej at bruge INSERT med flere værdier hvis det er praktisk. Det ser ud til at du allerede gør dette. Forsøg ikke at angive også mange værdier i en enkelt VALUES selvom; disse værdier skal passe ind i hukommelsen et par gange, så hold det til et par hundrede pr. udsagn.

  • Batch dine indstik til eksplicitte transaktioner, og lav hundredtusindvis eller millioner af indstik pr. transaktion. Der er ingen praktisk grænse AFAIK, men batching giver dig mulighed for at genoprette en fejl ved at markere starten af ​​hver batch i dine inputdata. Igen, du ser ud til at gøre dette allerede.

  • Brug synchronous_commit=off og en enorm commit_delay for at reducere fsync() omkostninger. Dette hjælper dog ikke meget, hvis du har samlet dit arbejde i store transaktioner.

  • INDSÆT eller COPY parallelt fra flere forbindelser. Hvor mange afhænger af din hardwares diskundersystem; som en tommelfingerregel, vil du have én forbindelse pr. fysisk harddisk, hvis du bruger direkte tilsluttet lager.

  • Indstil en høj max_wal_size værdi (checkpoint_segments i ældre versioner) og aktiver log_checkpoints . Se på PostgreSQL-logfilerne, og sørg for, at den ikke klager over kontrolpunkter, der forekommer for ofte.

  • Hvis og kun hvis du ikke har noget imod at miste hele din PostgreSQL-klynge (din database og eventuelle andre på samme klynge) til katastrofal korruption, hvis systemet går ned under importen, kan du stoppe Pg, indstille fsync=off , start Pg, foretag din import, stop derefter (vitalt) Pg og indstil fsync=on en gang til. Se WAL-konfiguration. Gør ikke dette, hvis der allerede er nogen data, du interesserer dig for, i en database på din PostgreSQL-installation. Hvis du indstiller fsync=off du kan også indstille full_page_writes=off; igen, bare husk at tænde den igen efter din import for at forhindre databasekorruption og datatab. Se ikke-holdbare indstillinger i Pg manualen.

Du bør også se på tuning af dit system:

  • Brug god kvalitet SSD'er til opbevaring så meget som muligt. Gode ​​SSD'er med pålidelige, strømbeskyttede tilbageskrivningscaches gør commit-hastigheder utroligt hurtigere. De er mindre fordelagtige, når du følger rådene ovenfor - hvilket reducerer diskudskydelser / antallet af fsync() s - men kan stadig være en stor hjælp. Brug ikke billige SSD'er uden ordentlig strømafbrydelsesbeskyttelse, medmindre du er ligeglad med at beholde dine data.

  • Hvis du bruger RAID 5 eller RAID 6 til direkte tilsluttet lager, skal du stoppe nu. Sikkerhedskopier dine data, omstrukturer dit RAID-array til RAID 10, og prøv igen. RAID 5/6 er håbløse for bulk-skriveydelse - selvom en god RAID-controller med en stor cache kan hjælpe.

  • Hvis du har mulighed for at bruge en hardware-RAID-controller med en stor batteri-understøttet tilbageskrivningscache, kan dette virkelig forbedre skriveydeevnen for arbejdsbelastninger med masser af commits. Det hjælper ikke så meget, hvis du bruger async commit med en commit_delay, eller hvis du laver færre store transaktioner under masseindlæsning.

  • Hvis det er muligt, gem WAL (pg_wal , eller pg_xlog i gamle versioner) på en separat disk / diskarray. Der er ingen mening i at bruge et separat filsystem på den samme disk. Folk vælger ofte at bruge et RAID1-par til WAL. Igen har dette mere effekt på systemer med høje commit-rater, og det har ringe effekt, hvis du bruger en ulogget tabel som dataindlæsningsmål.

Du kan også være interesseret i Optimer PostgreSQL til hurtig test.



  1. Konverter 'datetime offset' til 'smalldatetime' i SQL Server (T-SQL-eksempler)

  2. XAMPP - MySQL lukning uventet

  3. Rul A tilbage, hvis B går galt. fjederstøvle, jdbctemplate

  4. datagrip Kan ikke anvende ændringer Denne tabel er skrivebeskyttet. Ændringer i celleeditoren kan ikke anvendes