Database Indexing
PerformanceTeknik til at accelerere database queries ved at skabe datastrukturer der giver hurtigere søgning.
Beskrivelse
Database indexing er som indholdsfortegnelsen i en bog - i stedet for at scanne hele bogen (full table scan) for at finde information, kan du bruge indexet til at hoppe direkte til den rigtige side. Et index er en separat datastruktur (typisk B-tree eller hash table) 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 indexed kolonne, kan databasen bruge indexet til at finde rækkerne ekstremt hurtigt - ofte i O(log n) tid i stedet for O(n). Men indexes kommer med trade-offs: de bruger ekstra disk space, og hver write operation (INSERT, UPDATE, DELETE) bliver langsommere fordi indexet også skal opdateres. Derfor er det vigtigt at indexere strategisk - typisk på kolonner der bruges ofte i WHERE clauses, JOIN conditions, og ORDER BY statements. Der findes forskellige index typer: B-tree (standard, god til ranges), Hash (hurtig equality checks), GiST/GIN (full-text search, arrays), og Bitmap (for kolonner med få distinct values).
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 brugesFordele
- ✓Drastisk hurtigere queries (fra sekunder til millisekunder)
- ✓Reducerer database load
- ✓Forbedrer user experience
- ✓Muliggør efficient sorting og grouping
- ✓Enforcer uniqueness constraints
Udfordringer
- ⚠Ekstra disk space (kan være betydeligt)
- ⚠Langsommere writes (INSERT, UPDATE, DELETE)
- ⚠Index maintenance overhead
- ⚠For mange indexes kan skade performance
- ⚠Kræver analyse af query patterns
Anvendelsesområder
- •Foreign key kolonner i JOIN operations
- •Kolonner brugt ofte i WHERE clauses
- •Email, username til login lookups
- •Dato kolonner for date range queries
- •Sort keys i ORDER BY statements
Eksempler fra den virkelige verden
- •E-commerce produktsøgning (index på kategori, pris, brand)
- •Social media user lookup (index på username, email)
- •Blog article search (full-text index på content)
- •Finansielle transaktioner (index på dato, bruger ID)
- •Logfiler med timestamps (index på timestamp for queries)