codexier.

SaaS och MVP

Tecken på att databasen är flaskhalsen i appen

Av CodexierPublicerad 5 min läsning

En app som var snabb med hundra kunder och seg med tusen är sällan dåligt byggd. Oftast kör den frågor som fungerade bra på små tabeller men nu måste gå igenom stora. Det positiva är att databasproblem hör till de lättaste att felsöka i mjukvara: databasen kan tala om exakt vilka frågor som kostar mest. Här går vi igenom symptomen, hur du hittar bovarna, åtgärderna som löser de flesta fall och den ovanligare situationen där själva datamodellen måste ändras.

Symptom som användarna märker

  • Listvyer och sök blir långsammare vecka för vecka när kunderna lägger in mer data.
  • Det är segast för de största kunderna och går bra för nya.
  • Instrumentpaneler och rapporter går i timeout, särskilt i början av månaden.
  • Allt blir långsamt samtidigt vid toppar, och databasserverns processor eller antal anslutningar slår i taket.
  • Fel om för många anslutningar eller låsningar som går ut dyker upp i loggarna.

Är appen lika långsam för en kund med tio poster som för en med tiotusen, leta först på andra ställen: stora paket i frontend, långsamma anrop till tredje part eller en för liten server.

Hitta långsamma frågor

Mät innan du ändrar något. I PostgreSQL registrerar tillägget pg_stat_statements varje frågetyp med antal anrop och total tid; driftade plattformar som Supabase, AWS RDS och liknande visar samma data i en panel. Sortera på total tid, inte på det långsammaste enskilda anropet: en fråga som tar måttlig tid men körs tusentals gånger i minuten kostar ofta mer än den enda rapporten som tar flera sekunder.

  1. Slå på frågestatistik och en logg för långsamma frågor med en rimlig tröskel.
  2. Lista de tio frågor som tar mest total tid och de tio som körs oftast.
  3. Kör EXPLAIN ANALYZE på varje fråga mot realistisk data, inte en liten utvecklingsdatabas.
  4. Leta efter sekventiella genomsökningar av stora tabeller, radskattningar långt från verkligheten och sorteringar som hamnar på disk.
  5. Notera vilken endpoint eller skärm varje fråga hör till, så att åtgärden kan testas från användarens håll.

Index och frågemönster

ProblemDet du serVanlig åtgärd
Saknat indexSekventiell genomsökning av en stor tabell som filtreras på en kolumnIndex på filterkolumnen, eller ett sammansatt index som matchar filter och sortering
N+1-frågorEn fråga för listan, sedan en per radHämta relaterade rader i en fråga med join eller samlad uppslagning
För mycket dataAlla kolumner och rader hämtas och filtreras i kodenVälj bara nödvändiga kolumner, filtrera och sidindela i databasen
Offset-sidindelning långt inSida 500 är mycket långsammare än sida 1Sidindelning med nyckel på en indexerad kolumn
Funktioner på indexerade kolumnerIndexet finns men används inteIndexera uttrycket eller skriv om villkoret
Radnivåpolicyer med underfrågorVarje fråga betalar för en långsam policykontrollIndexera kolumnerna policyn använder och förenkla den

Index är inte gratis: varje index gör skrivningar något långsammare och tar lagring. Lägg till dem för uppmätta problem och ta bort oanvända.

I appar med flera kunder i samma databas, där varje tabell har en kolumn för kund eller organisation, bör nästan varje index börja med den kolumnen, eftersom nästan varje fråga filtrerar på den. Guiden om multi-tenant-arkitektur förklarar varför.

Cachning och läsrepliker

Anslutningspool

Serverlösa funktioner och många appinstanser kan ta slut på databasanslutningar. En pool som PgBouncer, eller den plattformen erbjuder, är ofta första åtgärden mot fel vid toppar.

Cachning

Cacha resultat som läses ofta och ändras sällan: referensdata, publika sidor och summeringar till instrumentpaneler. Det svåra är att ogiltigförklara, så börja med korta livstider.

Läsrepliker

Flytta tunga rapporter och analysfrågor till en replik så att de inte konkurrerar med användarnas trafik. Repliker ligger lite efter, så läs aldrig från dem direkt efter en skrivning som användaren väntar sig att se.

När datamodellen är problemet

Ibland ser exekveringsplanen bra ut och frågan är ändå långsam, eftersom datan har fel form för frågan. Tecken är listor sparade i JSON-kolumner som ni sedan filtrerar på, summor som räknas över miljontals rader vid varje sidladdning eller en tabell som används för flera orelaterade syften. Åtgärderna är riktade: summeringstabeller som uppdateras vid skrivning, att dela en tabell eller att flytta ett JSON-fält till riktiga kolumner. Det är omstrukturering, inte omskrivning, och guiden bygga om eller omstrukturera hjälper dig att avgöra.

När ni inte behöver oss: kan någon i teamet läsa en exekveringsplan löser stegen ovan de flesta fall internt. Extern hjälp lönar sig när ingen i teamet har optimerat databaser förut, när problemet bara syns under produktionslast eller när någon föreslår en omskrivning utan mätningar. Vår tjänst för skalning och optimering börjar alltid med mätning; se priser eller boka ett samtal.

Vanliga frågor

Ska vi byta databas?

Nästan aldrig som första steg. PostgreSQL och MySQL hanterar långt mer data än de flesta SaaS-produkter någonsin når, när frågor och index är rätt. Ett databasbyte är dyrt och flyttar oftast bara samma frågeproblem till ett nytt system.

Löser en större databasserver problemet?

Det köper tid och kan vara rätt kortsiktigt i en kris. Men ett saknat index eller ett N+1-mönster växer med datan, så en större server skjuter bara upp samma problem till en högre månadskostnad.

Hur undviker vi det här från början?

Testa med realistiska datamängder, granska exekveringsplaner för nya list- och sökfrågor, slå på frågestatistik från dag ett och titta på de tyngsta frågorna en gång i månaden. Det tar lite tid och fångar problemen medan de är små.

Är det ORM:en som är boven?

Inte i sig, men en ORM gör det lätt att av misstag skriva N+1-mönster och hämta för mycket data. Logga SQL:en som ORM:en genererar för de tyngsta skärmarna och använd dess funktioner för förladdning och kolumnval.

Ta reda på vad som faktiskt bromsar appen

Berätta vilken teknik ni använder och vilka skärmar som blivit långsamma. På en kvart kan vi säga var ni ska börja leta och om det troligen är en snabb åtgärd.

Boka ett kostnadsfritt 15-minuterssamtal