Förberedelse inför kodningsintervjuer · Lektion

När index skadar: skrivningar och selektivitet

Skrivförstärkning och varför ett index på en kolumn med låg selektivitet är oanvändbart.

Lektion 4 av 413 steg

När index skadar: skrivningar och selektivitet är en gratis lektion i Förberedelse inför kodningsintervjuer på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Förberedelse inför kodningsintervjuer, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Förberedelse inför kodningsintervjuer innehåller totalt 4 lektioner.

Frågan bakom frågan

Efter tre lektioner om varför index hjälper vänder intervjuare på frågan: ”Varför indexerar vi inte bara varje kolumn?” En stark kandidat förklarar att index medför verkliga kostnader för skrivningar samt för cache och lagring, och att vissa index inte ens kommer att användas av planeraren.

Den här lektionen tar upp de två stora anledningarna till att ett index kan skada: skrivförstärkning och låg selektivitet.

Varje index gör skrivningar långsammare

Ett index måste hållas synkroniserat med tabellen. Varje INSERT, varje DELETE och varje UPDATE av en indexerad kolumn måste också uppdatera indexstrukturen. Detta är skrivförstärkning: en radändring blir en skrivning till tabellen plus en skrivning per berört index.

En tabell med åtta index kräver ungefär nio gånger så mycket skrivarbete som en tabell utan index. För skrivintensiva tabeller eller tabeller med hög genomströmning är det en betydande kostnad.

Genomgångsexempel: Skrivkostnaden

Föreställ dig en händelsetabell som tar emot tusentals rader per sekund. Varje extra index gör att varje infogning kräver mer arbete: indexsidor delas, blad uppdateras och indexet konkurrerar om cachen.

För en append-only-tabell som domineras av skrivningar är det rätta svaret ofta få eller inga index utöver primärnyckeln, och att göra tunga läsningar på en läsreplik eller i ett datalager i stället.

-- Each of these indexes adds cost to EVERY insert below
CREATE INDEX ix_events_user ON events (user_id);
CREATE INDEX ix_events_type ON events (event_type);
CREATE INDEX ix_events_ts   ON events (created_at);

INSERT INTO events (user_id, event_type, created_at)
VALUES (42, 'click', now());  -- now updates table + 3 indexes

Vad selektivitet innebär

Selektivitet är hur väl en kolumn skiljer rader åt, det vill säga andelen rader som ett typiskt värde matchar. Hög selektivitet innebär få rader per värde, som för en e-postadress eller en UUID. Låg selektivitet innebär många rader per värde, som för en boolesk kolumn eller en statuskolumn med tre alternativ.

Index lönar sig på kolumner med hög selektivitet, där en uppslagning eliminerar nästan alla rader. På kolumner med låg selektivitet gör de ofta inte det.

Varför ett index med låg selektivitet är oanvändbart

Anta att is_active är true för 90 % av användarna. En indexuppslagning skulle returnera 90 % av tabellen, och för så många rader skulle motorn göra en heap-hämtning per rad, vilket är långsammare än att helt enkelt skanna tabellen sekventiellt i ett enda pass.

Planeraren ignorerar därför indexet korrekt och gör en sekventiell skanning. Indexet medför då bara extra skrivarbete och lagringsutrymme, utan någon läsvinst alls.

-- 90% of rows match: the planner will likely skip this index
CREATE INDEX ix_users_active ON users (is_active);
SELECT * FROM users WHERE is_active = true;

Den ungefärliga gränsen

En användbar tumregel att nämna: när ett predikat matchar mer än ungefär 5 till 20 % av en tabell är en sekventiell skanning vanligtvis snabbare än en indexskanning, eftersom slumpmässiga hämtningar från heapen kostar mer än att läsa sidorna sekventiellt.

Den exakta brytpunkten beror på radstorlek, cachning och lagringshastighet. Därför använder planeraren statistik, inte ett fast tal, när den fattar beslutet.

Partiella index till undsättning

Om du bara frågar efter de sällsynta värdena i en snedfördelad kolumn kan ett partiellt index (Postgres) indexera enbart dessa rader – litet, selektivt och billigt att underhålla.

Om 1 % av beställningarna har statusen pending och det är dessa du ständigt frågar efter, indexerar du bara dem. Indexet förblir litet och planeraren använder det gärna.

-- Index only the rare, frequently-queried rows
CREATE INDEX ix_orders_pending
  ON orders (created_at)
  WHERE status = 'pending';

Föråldrad statistik vilseleder planeraren

Optimeraren fattar beslutet mellan index och skanning utifrån kolumnstatistik. Om statistiken är föråldrad, exempelvis efter en massinläsning eller en stor uppdatering, kan optimeraren felbedöma selektiviteten och välja fel plan.

När en intervjuare säger ”indexet finns men används inte” bör ett bra svar innehålla att statistiken uppdateras med ANALYZE innan du skyller på själva indexet.

ANALYZE orders;  -- refresh planner statistics

Andra sätt som index kan skada

Avrunda svaret med de mindre kända kostnaderna:

  • Lagring och cache: index tar upp diskutrymme och konkurrerar om minnet, vilket tränger undan användbara datasidor.
  • Redundanta/överlappande index: underhålls men väljs aldrig.
  • Bloat: under omfattande uppdateringar fragmenteras B-träd och behöver REINDEX.
  • Förvirring för optimeraren: för många liknande index gör planeringen långsammare och mindre förutsägbar.

Hitta oanvända index

För att motivera en rensning i ett verkligt system kan du nämna att Postgres följer indexanvändningen. Index med idx_scan = 0 är kandidater för borttagning: de kostar skrivningar och utrymme utan att någonsin användas för läsningar.

SELECT relname AS table_name, indexrelname AS index_name, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY relname;

Så formulerar du det på intervjun

En komplett och balanserad sammanfattning:

”Index medför skrivförstärkning: varje INSERT, UPDATE och DELETE underhåller dem, och dessutom tillkommer tryck på lagring och cache. De lönar sig bara för predikat med hög selektivitet; i en kolumn där de flesta rader matchar föredrar planeraren med rätta en sekventiell skanning, så indexet är en ren kostnad. För snedfördelade kolumner använder jag ett partiellt index, håller statistiken aktuell med ANALYZE och tar bort oanvända index.”

Snabbkontroll

Avgör vilket index som minst sannolikt är värt kostnaden.

Sammanfattning: När index gör skada

Viktiga slutsatser:

  • Varje index medför skrivförstärkning samt kostnader för lagring och cache.
  • Index hjälper på kolumner med hög selektivitet; på kolumner med låg selektivitet föredrar planeraren en sekventiell skanning.
  • När mer än ungefär 5 till 20 % av raderna matchar vinner en skanning vanligtvis.
  • Använd ett partiellt index för snedfördelade kolumner som du bara frågar efter med de sällsynta värdena.
  • Håll statistiken aktuell med ANALYZE och ta bort oanvända index (idx_scan = 0).

Därmed är kursen i indexstrategi klar: skapa index där de gör nytta och bevisa det med planen.

Gratis att börja

Lär dig Förberedelse inför kodningsintervjuer med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
90
Lektioner
360

Vanliga frågor

Är lektionen ”När index skadar: skrivningar och selektivitet” gratis?

Ja – hela texten till ”När index skadar: skrivningar och selektivitet” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Förberedelse inför kodningsintervjuer, kan Ni uppgradera till CoddyKit PRO. Kursen i Förberedelse inför kodningsintervjuer innehåller totalt 4 lektioner.

Vad lär jag mig i ”När index skadar: skrivningar och selektivitet”?

Skrivförstärkning och varför ett index på en kolumn med låg selektivitet är oanvändbart. Ni övar på Förberedelse inför kodningsintervjuer med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Förberedelse inför kodningsintervjuer?

Du behöver inga förkunskaper. Utbildningen i Förberedelse inför kodningsintervjuer på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.

Hur lång tid tar lektionen ”När index skadar: skrivningar och selektivitet”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Förberedelse inför kodningsintervjuer-lektionen?

Ja. Varje Förberedelse inför kodningsintervjuer-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. B-trädindex och hur de hjälper
  2. Kolumnordning i sammansatta index
  3. Täckande index och Index-Only-skanning
  4. När index skadar: skrivningar och selektivitet
← Tillbaka till Förberedelse inför kodningsintervjuer