En hurtig PostgreSQL-database er en database, hvor de data, der ofte læses, kan ligge i hukommelsen. Hele dimensioneringen tager udgangspunkt i det: databasens størrelse, den del, der reelt arbejdes med, antallet af forbindelser og derefter disken og dens margin. Denne guide giver dig metoden, startindstillingerne til 4, 8 og 16 GB hukommelse og de forespørgsler, der måler en eksisterende database.
shared_buffers på 25 % af hukommelsen, effective_cache_size på 75 %, random_page_cost = 1.1 på NVMe-SSD.pg_dump, uden for serveren, og gendan regelmæssigt for at kontrollere den.Hukommelsen på en databaseserver fungerer først og fremmest som cache: en side, der læses fra hukommelsen, leveres langt hurtigere end en side, der læses fra disken, selv en NVMe-disk. Spørgsmålet er derfor ikke kun «hvor meget fylder databasen?», men «hvor stor en del læses ofte?». En database på 50 GB, hvor kun de seneste tolv måneder bruges, arbejder måske på 8 GB.
På en eksisterende database giver to forespørgsler den samlede størrelse og de største tabeller, indeks medregnet:
SELECT pg_size_pretty(pg_database_size(current_database()));
SELECT relname AS tabel,
pg_size_pretty(pg_total_relation_size(relid)) AS storrelse_med_indeks
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 10;
For en kommende database skønner du tabel for tabel: antal forventede rækker om et år × gennemsnitlig rækkestørrelse, og derefter lægger du indeksene til, som ofte fylder 30 til 100 % af dataene. Eksempel: 2 millioner rækker om måneden på 500 byte hver giver 12 GB data om et år og 18 til 24 GB med indeks.
PostgreSQL holder de læste sider på to niveauer: sin egen cache (shared_buffers) og systemets filcache. Dokumentationen anbefaler at starte med 25 % af hukommelsen til shared_buffers på en dedikeret server og bemærker, at gevinsten bliver sjælden over 40 %: resten kommer systemets cache og sorteringerne til gode.
| Parameter | 4 GB | 8 GB | 16 GB | Rolle |
|---|---|---|---|---|
shared_buffers | 1 GB | 2 GB | 4 GB | PostgreSQL's egen cache |
effective_cache_size | 3 GB | 6 GB | 12 GB | Den anslåede samlede cache, som styrer valget af forespørgselsplaner |
work_mem | 8 MB | 16 MB | 32 MB | Hukommelsen til hver sortering eller hashing pr. forbindelse: skal ganges med antallet af samtidige forespørgsler |
maintenance_work_mem | 256 MB | 512 MB | 1 GB | Oprettelse af indeks og VACUUM |
random_page_cost | 1.1 | 1.1 | 1.1 | Den anslåede omkostning ved en tilfældig læsning: 4 som standard, langt over den reelle omkostning på NVMe-SSD |
Disse værdier forudsætter, at databasen står alene på serveren. Kører applikationen ved siden af, så træk først dens hukommelse fra (processer, cache, kompilering), og anvend procentsatserne på resten: en server med 8 GB, der kører en applikation på 3 GB, indstilles som en database med 5 GB.
shared_buffers = 2GB
effective_cache_size = 6GB
work_mem = 16MB
maintenance_work_mem = 512MB
random_page_cost = 1.1
shared_buffers træder først i kraft, når PostgreSQL genstartes; de andre parametre genindlæses uden afbrydelse med SELECT pg_reload_conf();.
For at vide, om hukommelsen er tilstrækkelig, læser du cache-hitraten. For en forretningsapplikation eller en hjemmeside ligger den over 99 %:
SELECT round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 2) AS cache_hitrate
FROM pg_stat_database
WHERE datname = current_database();
PostgreSQL åbner én proces pr. forbindelse og accepterer 100 som standard (max_connections). Hver proces optager nogle få megabyte i hvile, mere når den sorterer eller hasher data (work_mem, nogle gange flere gange i samme forespørgsel). At hæve max_connections til 500 for at følge med en snakkesalig applikation er at risikere, at serveren løber tør for hukommelse ved første spidsbelastning.
Det rigtige svar er en connection pooler: PgBouncer i transaction-tilstand lader hundredvis af applikationsforbindelser dele nogle titals reelle forbindelser. Frameworks har også deres egen pool (SQLAlchemy, Prisma, HikariCP): indstil dens størrelse efter antallet af vCPU på databaseserveren frem for efter antallet af brugere.
Disken på en PostgreSQL-server rummer mere end tabellerne:
max_wal_size), mere under en massiv import og endnu mere, hvis arkiveringen af loggen kommer bagud.work_mem.VACUUM FULL og genopbygning af et indeks skriver en komplet kopi, før den gamle frigives.Reglen: størrelsen om et år plus mindst 30 % margin. Det er ikke luksus: når den disk, der rummer transaktionsloggen, bliver fuld, stopper PostgreSQL for at beskytte sine data. Hold øje med pladsforbruget, og udvid, før det når 80 %.
Hvad ydeevnen angår, venter hver bekræftelse af en transaktion på, at loggen er skrevet til disken: lagerets latenstid bestemmer skrivehastigheden. Det er her, en NVMe-SSD gør forskellen, langt mere end ved læsninger, som hukommelsen allerede leverer.
En PostgreSQL-forespørgsel kører på en enkelt kerne, bortset fra de store læsninger, som motoren paralleliserer. Antallet af vCPU bestemmer derfor antallet af tunge forespørgsler, der behandles samtidig: 2 vCPU er nok til en forretningsapplikation ved lanceringen, 4 til 8 passer til meget belastede databaser og tunge rapporter.
Før du tilføjer vCPU, så find de forespørgsler, der bruger dem. Udvidelsen pg_stat_statements sorterer dem efter samlet tid:
shared_preload_libraries = 'pg_stat_statements'
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT calls, round(total_exec_time) AS ms_total,
round(mean_exec_time::numeric, 1) AS ms_gennemsnit, query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
Ved lanceringen er databasen på samme server som applikationen det rigtige valg: ingen netværkslatens mellem de to, forbindelse via Unix-socket, én server at tage backup af og overvåge. Man skiller dem ad, når de to konkurrerer om ressourcerne: en kompilering eller en trafikspids, der tømmer databasens cache, en database, der har brug for al hukommelsen til sine data, eller forskellige krav til backup.
listen_addresses = 'localhost', så længe kun applikationen på serveren forbinder. Skal en anden server have adgang, åbner du port 5432 for dens adresse alene, i firewallen og i pg_hba.conf.scram-sha-256 i pg_hba.conf, én rolle pr. applikation, uden superbrugerrettigheder.pg_dump, kopieret uden for serveren.pg_dump -Fc -d min_database -f min_database-$(date +%F).dump
createdb min_database_test
pg_restore -d min_database_test min_database-2026-10-29.dump
VPS Pro kører på Intel Xeon-processorer, ECC-hukommelse, der retter fejl i realtid, og spejlede NVMe-SSD'er, med hver datablok verificeret med kontrolsum og en krypteret backup hver nat uden for maskinen. Totalsupport er inkluderet: når din database bliver langsom, analyserer vi de langsomme forespørgsler og indeksene og fortæller dig derefter, hvilke indstillinger der giver din applikation dens hastighed tilbage.
Nok til, at de data, der ofte læses, kan ligge i hukommelsen. Til en forretningsapplikation ved lanceringen er 4 GB nok, database og applikation medregnet. Derefter måler du cache-hitraten: så længe den holder sig over 99 %, er hukommelsen tilstrækkelig.
25 % af hukommelsen på en server, der er dedikeret til databasen, som PostgreSQL's dokumentation anbefaler: 1 GB på 4 GB, 2 GB på 8 GB, 4 GB på 16 GB. Over 40 % bliver gevinsten sjælden, fordi systemets cache klarer resten.
PostgreSQL accepterer 100 som standard, og hver forbindelse er en proces, der bruger hukommelse. I stedet for at hæve det loft sætter du en connection pooler som PgBouncer foran databasen: nogle titals reelle forbindelser betjener så hundredvis af applikationsforbindelser.
Ikke ved lanceringen: på samme server svarer databasen uden netværkslatens, og det hele tages der backup af i ét. Man skiller dem ad, når den ene generer den anden, for eksempel når en kompilering eller en trafikspids tømmer databasens cache.
Simafri
Lad os tale om din hjemmeside
Fortæl os om dit projekt med få ord: vi vender hurtigt tilbage til dig.
Tak! Din forespørgsel er sendt. Vi vender tilbage til dig hurtigst muligt.
Foretrækker du e-mail? Skriv til os på support@simafri.com.