sql >> Database >  >> RDS >> PostgreSQL

Hoe de invoegprestaties in PostgreSQL te versnellen

Zie een database vullen in de PostgreSQL-handleiding, het uitstekende artikel van depesz over dit onderwerp en deze SO-vraag.

(Merk op dat dit antwoord gaat over het bulksgewijs laden van gegevens in een bestaande DB of om een ​​nieuwe te maken. Als u geïnteresseerd bent in de prestaties van DB-herstel met pg_restore of psql uitvoering van pg_dump uitvoer, is veel hiervan niet van toepassing sinds pg_dump en pg_restore doe al dingen zoals het maken van triggers en indexen nadat het een schema+gegevensherstel heeft voltooid) .

Er is veel te doen. De ideale oplossing zou zijn om te importeren in een UNLOGGED tabel zonder indexen, verander het dan in gelogd en voeg de indexen toe. Helaas is er in PostgreSQL 9.4 geen ondersteuning voor het wijzigen van tabellen van UNLOGGED te loggen. 9.5 voegt ALTER TABLE toe ... SET LOGGED om u toe te staan ​​dit te doen.

Als u uw database offline kunt halen voor de bulkimport, gebruik dan pg_bulkload .

Anders:

  • Schakel eventuele triggers op de tafel uit

  • Laat indexen vallen voordat u met importeren begint, en maak ze daarna opnieuw. (Het kost veel minder tijd om een ​​index in één keer op te bouwen dan om dezelfde gegevens er geleidelijk aan toe te voegen, en de resulterende index is veel compacter).

  • Als u de import binnen een enkele transactie uitvoert, is het veilig om beperkingen voor externe sleutels op te heffen, de import uit te voeren en de beperkingen opnieuw te maken voordat u zich commit. Doe dit niet als de import is verdeeld over meerdere transacties, omdat u mogelijk ongeldige gegevens invoert.

  • Gebruik indien mogelijk COPY in plaats van INSERT s

  • Als u COPY niet kunt gebruiken overweeg het gebruik van INSERT met meerdere waarden s indien praktisch. Je lijkt dit al te doen. Probeer niet te op te sommen veel waarden in één VALUES hoewel; die waarden moeten een paar keer in het geheugen passen, dus houd het op een paar honderd per statement.

  • Batch uw inserts in expliciete transacties, waarbij u honderdduizenden of miljoenen inserts per transactie doet. Er is geen praktische limiet voor AFAIK, maar met batchen kunt u een fout herstellen door het begin van elke batch in uw invoergegevens te markeren. Nogmaals, je lijkt dit al te doen.

  • Gebruik synchronous_commit=off en een enorme commit_delay om fsync()-kosten te verlagen. Dit zal echter niet veel helpen als je je werk in grote transacties hebt gebundeld.

  • INSERT of KOPIE parallel van verschillende verbindingen. Hoeveel hangt af van het schijfsubsysteem van uw hardware; als vuistregel wilt u één verbinding per fysieke harde schijf als u direct aangesloten opslag gebruikt.

  • Stel een hoge max_wal_size in waarde (checkpoint_segments in oudere versies) en schakel log_checkpoints . in . Bekijk de PostgreSQL-logboeken en zorg ervoor dat het niet klaagt over te vaak voorkomende controlepunten.

  • Als en alleen als je het niet erg vindt om je hele PostgreSQL-cluster (je database en alle andere op hetzelfde cluster) te verliezen aan catastrofale corruptie als het systeem crasht tijdens het importeren, kun je Pg stoppen, fsync=off , start Pg, voer uw import uit, stop dan (vitaal) Pg en stel fsync=on in nog een keer. Zie WAL-configuratie. Doe dit niet als er al gegevens zijn die u belangrijk vindt in een database op uw PostgreSQL-installatie. Als u fsync=off . instelt je kunt ook full_page_writes=off . instellen; nogmaals, vergeet niet om het na het importeren weer in te schakelen om beschadiging van de database en gegevensverlies te voorkomen. Zie niet-duurzame instellingen in de Pg-handleiding.

Je moet ook kijken naar het afstemmen van je systeem:

  • Gebruik goede kwaliteit SSD's voor opslag zoveel mogelijk. Goede SSD's met betrouwbare, stroombeveiligde terugschrijfcaches maken de commit-snelheden ongelooflijk sneller. Ze zijn minder gunstig als u het bovenstaande advies opvolgt - wat het aantal schijfopruimingen / aantal fsync() vermindert s - maar kan nog steeds een grote hulp zijn. Gebruik geen goedkope SSD's zonder de juiste bescherming tegen stroomuitval, tenzij u uw gegevens niet wilt bewaren.

  • Als u RAID 5 of RAID 6 gebruikt voor direct aangesloten opslag, stop dan nu. Maak een back-up van uw gegevens, herstructureer uw RAID-array naar RAID 10 en probeer het opnieuw. RAID 5/6 is hopeloos voor bulkschrijfprestaties, hoewel een goede RAID-controller met een grote cache kan helpen.

  • Als je de mogelijkheid hebt om een ​​hardware RAID-controller te gebruiken met een grote terugschrijfcache met batterijvoeding, kan dit de schrijfprestaties voor workloads met veel commits echt verbeteren. Het helpt niet zo veel als je asynchrone commit gebruikt met een commit_delay of als je minder grote transacties doet tijdens het bulksgewijs laden.

  • Sla indien mogelijk WAL op (pg_wal , of pg_xlog in oude versies) op een aparte schijf / schijfarray. Het heeft weinig zin om een ​​apart bestandssysteem op dezelfde schijf te gebruiken. Mensen kiezen er vaak voor om een ​​RAID1-paar te gebruiken voor WAL. Nogmaals, dit heeft meer effect op systemen met hoge vastleggingspercentages, en het heeft weinig effect als je een niet-gelogde tabel gebruikt als doel voor het laden van gegevens.

Mogelijk bent u ook geïnteresseerd in PostgreSQL optimaliseren voor snel testen.



  1. Kan ik de tabelnaam in een voorbereide instructie parametriseren?

  2. Hoe CDC op een reeks tabellen uit te schakelen OF op alle tabellen in een database in SQL Server uit te schakelen - SQL Server-zelfstudie

  3. MySQL Galera-cluster herstellen van een asynchrone slaaf

  4. Hoe Cosh() werkt in PostgreSQL