Först, använd alltid den senaste versionen av PostgreSQL. Prestandaförbättringar kommer alltid, så du slösar förmodligen bort din tid om du finjusterar en gammal version. PostgreSQL 9.2 förbättrar till exempel hastigheten för TRUNCATE
avsevärt och lägger naturligtvis till endast index-skanningar. Även mindre släpp bör alltid följas; se versionspolicyn.
Gör inte
Gör INTE lägg ett tabellutrymme på en RAM-disk eller annan icke-hållbar lagring.
Om du förlorar ett tabellutrymme kan hela databasen vara skadad och svår att använda utan betydande arbete. Det finns väldigt små fördelar med detta jämfört med att bara använda UNLOGGED
tabeller och ha massor av RAM-minne för cache i alla fall.
Om du verkligen vill ha ett ramdiskbaserat system, initdb
ett helt nytt kluster på ramdisken av initdb
en ny PostgreSQL-instans på ramdisken, så att du har en helt disponibel PostgreSQL-instans.
PostgreSQL-serverkonfiguration
När du testar kan du konfigurera din server för icke-hållbar men snabbare drift.
Detta är en av de enda acceptabla användningsområdena för fsync=off
inställning i PostgreSQL. Den här inställningen säger i stort sett till PostgreSQL att inte bry sig om beställda skrivningar eller något annat otäckt dataintegritetsskydd och kraschsäkerhetsgrejer, vilket ger den tillåtelse att fullständigt slänga din data om du tappar strömmen eller har en OS-krasch.
Naturligtvis bör du aldrig aktivera fsync=off
i produktion om du inte använder Pg som en tillfällig databas för data som du kan återskapa från någon annanstans. Om och bara om du gör för att stänga av fsync kan du också stänga av full_page_writes
av, eftersom det inte längre gör någon nytta då. Tänk på att fsync=off
och full_page_writes
ansök på klustret nivå, så de påverkar alla databaser i din PostgreSQL-instans.
För produktionsanvändning kan du eventuellt använda synchronous_commit=off
och ställ in en commit_delay
, eftersom du får många av samma fördelar som fsync=off
utan den gigantiska risken för datakorruption. Du har visserligen ett litet fönster för förlust av senaste data om du aktiverar async commit - men det är allt.
Om du har möjlighet att ändra DDL något kan du också använda UNLOGGED
tabeller i Pg 9.1+ för att helt undvika WAL-loggning och få en rejäl fartökning till priset av att tabellerna raderas om servern kraschar. Det finns inget konfigurationsalternativ för att göra alla tabeller ologgade, det måste ställas in under CREATE TABLE
. Förutom att vara bra för att testa är detta praktiskt om du har tabeller fulla av genererad eller oviktig data i en databas som annars innehåller saker du behöver för att vara säker.
Kontrollera dina loggar och se om du får varningar om för många kontrollpunkter. Om du är det bör du öka dina checkpoint_segments. Du kanske också vill ställa in ditt checkpoint_completion_target för att jämna ut skrivningar.
Ställ in shared_buffers
för att passa din arbetsbörda. Detta är OS-beroende, beror på vad mer som händer med din maskin, och kräver en del försök och fel. Standardvärdena är extremt konservativa. Du kan behöva öka operativsystemets maximala delade minnesgräns om du ökar shared_buffers
på PostgreSQL 9.2 och nedan; 9.3 och senare ändrade hur de använder delat minne för att undvika det.
Om du bara använder ett par anslutningar som gör mycket arbete, öka work_mem
för att ge dem mer RAM-minne att leka med för sorteringar etc. Se upp för hög work_mem
inställningen kan orsaka problem med slut på minnet eftersom det är per sort inte per anslutning så en fråga kan ha många kapslade sorteringar. Du bara egentligen måste öka work_mem
om du kan se sorters spill till disken i EXPLAIN
eller loggas med log_temp_files
inställning (rekommenderas), men ett högre värde kan också låta Pg välja smartare planer.
Som sagt av en annan affisch här är det klokt att lägga xlog och huvudtabellerna/indexen på separata hårddiskar om möjligt. Separata partitioner är ganska meningslöst, du vill verkligen ha separata enheter. Denna separation har mycket mindre fördelar om du kör med fsync=off
och nästan ingen om du använder UNLOGGED
tabeller.
Slutligen, finjustera dina frågor. Se till att din random_page_cost
och seq_page_cost
återspeglar ditt systems prestanda, se till din effective_cache_size
är korrekt, etc. Använd EXPLAIN (BUFFERS, ANALYZE)
för att undersöka individuella frågeplaner och aktivera auto_explain
modul på för att rapportera alla långsamma frågor. Du kan ofta förbättra frågeprestanda dramatiskt bara genom att skapa ett lämpligt index eller justera kostnadsparametrarna.
AFAIK det finns inget sätt att ställa in en hel databas eller kluster som UNLOGGED
. Det skulle vara intressant att kunna göra det. Överväg att fråga på PostgreSQL-sändlistan.
Inställning av värdoperativsystem
Det finns en del justeringar du kan göra på operativsystemnivå också. Det viktigaste du kanske vill göra är att övertyga operativsystemet att inte spola skrivningar till disk aggressivt, eftersom du verkligen inte bryr dig när/om de kommer till disken.
I Linux kan du styra detta med det virtuella minnesundersystemets dirty_*
inställningar, som dirty_writeback_centisecs
.
Det enda problemet med att ställa in återskrivningsinställningarna för att vara för slappa är att en spolning av något annat program kan orsaka att alla PostgreSQL:s ackumulerade buffertar töms också, vilket orsakar stora stopp medan allt blockerar skrivningar. Du kanske kan lindra detta genom att köra PostgreSQL på ett annat filsystem, men vissa tömningar kan vara på enhetsnivå eller hela värdnivå inte filsystemnivå, så du kan inte lita på det.
Denna justering kräver verkligen att du leker med inställningarna för att se vad som fungerar bäst för din arbetsbelastning.
På nyare kärnor kanske du vill se till att vm.zone_reclaim_mode
är inställd på noll, eftersom det kan orsaka allvarliga prestandaproblem med NUMA-system (de flesta system nuförtiden) på grund av interaktioner med hur PostgreSQL hanterar shared_buffers
.
Justering av frågor och arbetsbelastning
Det här är saker som kräver kodändringar; de kanske inte passar dig. Vissa är saker du kanske kan tillämpa.
Om du inte batchar arbete i större transaktioner, börja. Många små transaktioner är dyra, så du bör batcha saker när det är möjligt och praktiskt att göra det. Om du använder async commit är detta mindre viktigt, men rekommenderas fortfarande starkt.
Använd tillfälliga tabeller när det är möjligt. De genererar inte WAL-trafik, så de är mycket snabbare för infogningar och uppdateringar. Ibland är det värt att slurpa in en massa data i en temporär tabell, manipulera den hur du vill och sedan göra en INSERT INTO ... SELECT ...
för att kopiera det till finalbordet. Observera att tillfälliga tabeller är per-session; om din session slutar eller om du tappar anslutningen försvinner temptabellen, och ingen annan anslutning kan se innehållet i en sessions temptabell(er).
Om du använder PostgreSQL 9.1 eller senare kan du använda UNLOGGED
tabeller för data du har råd att förlora, som sessionstillstånd. Dessa är synliga över olika sessioner och bevaras mellan anslutningar. De trunkeras om servern stängs av orent så att de inte kan användas till något du inte kan återskapa, men de är utmärkta för cacher, materialiserade vyer, tillståndstabeller, etc.
Generellt sett DELETE FROM blah;
. Använd TRUNCATE TABLE blah;
istället; det går mycket snabbare när du dumpar alla rader i en tabell. Trunkera många tabeller i en TRUNCATE
ring om du kan. Det finns en varning om du gör många TRUNCATES
av små bord om och om igen, dock; se:Postgresql trunkeringshastighet
Om du inte har index på främmande nycklar, DELETE
s som involverar primärnycklarna som refereras till av dessa främmande nycklar kommer att vara fruktansvärt långsamma. Se till att skapa sådana index om du någonsin förväntar dig att DELETE
från den eller de refererade tabellerna. Index krävs inte för TRUNCATE
.
Skapa inte index som du inte behöver. Varje index har en underhållskostnad. Försök att använda en minimal uppsättning index och låt bitmappsindexskanningar kombinera dem istället för att behålla för många enorma, dyra index med flera kolumner. Om index krävs, försök att fylla i tabellen först och skapa sedan index i slutet.
Hårdvara
Att ha tillräckligt med RAM för att hålla hela databasen är en stor vinst om du kan hantera den.
Om du inte har tillräckligt med RAM, desto snabbare lagring du kan få desto bättre. Även en billig SSD gör en enorm skillnad jämfört med snurrrost. Lita dock inte på billiga SSD-enheter för produktion, de är ofta inte kraschsäkra och kan äta upp din data.
Lärande
Greg Smiths bok, PostgreSQL 9.0 High Performance är fortfarande relevant trots att den hänvisar till en något äldre version. Det borde vara en användbar referens.
Gå med i PostgreSQL allmänna e-postlista och följ den.
Läser:
- Justera din PostgreSQL-server - PostgreSQL wiki
- Antal databasanslutningar - PostgreSQL wiki