← Tilbage til koncepter

Database Indexing

Ydeevne

Teknik til at accelerere databaseforespørgsler ved at skabe datastrukturer der giver hurtigere søgning.

Beskrivelse

Database-indeksering er som indholdsfortegnelsen i en bog - i stedet for at scanne hele bogen (fuld tabelscanning) for at finde information, kan du bruge indekset til at hoppe direkte til den rigtige side. Et indeks er en separat datastruktur (typisk B-tree eller hash-tabel) der holder en sorteret kopi af udvalgte kolonner sammen med pointere til de faktiske rækker. Når du søger efter data via en indekseret kolonne, kan databasen bruge indekset til at finde rækkerne ekstremt hurtigt - ofte i O(log n) tid i stedet for O(n). Men indekser kommer med afvejninger: de bruger ekstra diskplads, og hver skriveoperations (INSERT, UPDATE, DELETE) bliver langsommere fordi indekset også skal opdateres. Derfor er det vigtigt at indeksere strategisk - typisk på kolonner der bruges ofte i WHERE-klausuler, JOIN-betingelser og ORDER BY-sætninger. Der findes forskellige indekstyper: B-tree (standard, god til intervaller), Hash (hurtig lighedskontrol), GiST/GIN (fuldtekstsøgning, arrays) og Bitmap (for kolonner med få distinkte værdier).

Problem

Uden indexes må databasen scanne hver række i en tabel for at finde matches (full table scan), hvilket er ekstremt langsomt for store tabeller. En query der søger efter én bruger blandt millioner kan tage sekunder.

Løsning

Indexer opretter sorterede lookup strukturer der lader databasen finde data i logaritmisk tid. Som at søge i en telefonbog - du springer direkte til det rigtige afsnit i stedet for at læse hver side.

Eksempel

-- Uden index: Full table scan (langsomt)
SELECT * FROM users WHERE email = 'maria@email.dk';
-- Database scanner ALLE rækker: O(n) tid

-- Opret index på email kolonne
CREATE INDEX idx_users_email ON users(email);
-- Nu bruger databasen B-tree index: O(log n) tid

SELECT * FROM users WHERE email = 'maria@email.dk';
-- Meget hurtigere med index!

-- Composite index for multiple kolonner
CREATE INDEX idx_users_city_age ON users(city, age);
SELECT * FROM users WHERE city = 'København' AND age > 25;
-- Effektiv hvis begge kolonner bruges sammen

-- Unique index sikrer unikke værdier
CREATE UNIQUE INDEX idx_users_email_unique ON users(email);
-- Forhindrer duplicate emails

-- Partial index (PostgreSQL)
CREATE INDEX idx_active_users ON users(last_login)
WHERE active = true;
-- Indexer kun aktive brugere

-- Full-text search index (PostgreSQL)
CREATE INDEX idx_articles_content ON articles 
USING GIN(to_tsvector('danish', content));
-- Hurtig text søgning

-- Se hvilke indexes der bruges
EXPLAIN ANALYZE
SELECT * FROM users WHERE email = 'maria@email.dk';
-- Viser query plan og om index bruges

Fordele

  • Drastisk hurtigere forespørgsler (fra sekunder til millisekunder)
  • Reducerer databasebelastning
  • Forbedrer brugeroplevelsen
  • Muliggør effektiv sortering og gruppering
  • Håndhæver unikhedsbegrænsninger

Udfordringer

  • Ekstra diskplads (kan være betydeligt)
  • Langsommere skrivninger (INSERT, UPDATE, DELETE)
  • Indeksvedligeholdelses-overhead
  • For mange indekser kan skade ydeevnen
  • Kræver analyse af forespørgselsmønstre

Anvendelsesområder

  • Fremmednøglekolonner i JOIN-operationer
  • Kolonner brugt ofte i WHERE-klausuler
  • Email, brugernavn til login-opslag
  • Datokolonner til datointervalsforespørgsler
  • Sorteringsnøgler i ORDER BY-sætninger

Eksempler fra den virkelige verden

  • E-handels produktsøgning (indeks på kategori, pris, mærke)
  • Sociale medier brugeropslag (indeks på brugernavn, email)
  • Blog-artikelsøgning (fuldtekstindeks på indhold)
  • Finansielle transaktioner (indeks på dato, bruger-ID)
  • Logfiler med tidsstempler (indeks på tidsstempel til forespørgsler)