Et cheat sheet om SQL-indextyper, designmønstre og vedligeholdelse.
Indekser bytter lagerplads og skrivehastighed for læsehastighed. Vælg strukturen, afgræns rækkerne, og hold oppustetheden nede.
Referencetabel · 31 poster
SQL-indekseringExplained
31 of 31 rows
Indextyper
Balanceret træ til lighed, intervaller og sorterede scanninger. Standard i de fleste databaser.
Brug til =, <, >, BETWEEN, ORDER BY. Undlad ved fuldtekstsøgning.
Indeks, hvis bladniveau er selve tabellen. Rækker gemmes i nøglerækkefølge. Ét pr. tabel.
InnoDB klynger på primærnøglen. SQL Server-tabeller uden et er heaps.
Separat struktur med nøgler plus en pegepind tilbage til basistabellen. Mange pr. tabel.
På et heap gemmer den et row-ID; på en tabel med clustered indeks gemmer den klyngenøglen.
Hashtabel kun til opslag på lighed. Nøjagtigt match i konstant tid.
Brug kun til =-operationer; intervaller og sortering kræver B-tree. Hash på memory-optimized tabeller i SQL Server kræver et bucket count tæt på antallet af rækker.
Generalized Inverted Index. Afbilder værdier på rækker. Bygget til arrays og fuldtekst.
Brug til jsonb, arrays, tsvector og trigram-søgning. Langsommere at bygge end B-tree.
Generalized Search Tree. Udvidelsesvenlig til ikke-skalære typer og overlap-forespørgsler.
Brug til geometriske intervaller, kNN og exclusion-begrænsninger. pg_trgm fremskynder LIKE.
Rumopdelt GiST. Deler data i ikke-overlappende regioner via radix- eller quad-træer.
Brug til punkter, IP-præfikser og præfiks-match. Ikke til overlap-forespørgsler; brug GiST.
Block Range Index. Gemmer min/maks pr. blokinterval. Bittet lille fodaftryk.
Brug på store, fysisk sorterede tabeller. Billigt at bygge, svag selektivitet.
Indeks gemt som kolonnesegmenter i stedet for rækker. Høj komprimering, batchkørsel.
Brug til analytiske scanninger over mange rækker og få kolonner. Opslag på enkeltrækker er langsomme.
Dedikeret inverteret ordindeks i MySQL og SQL Server. Bygges pr. tekstkolonne.
Brug MATCH AGAINST eller CONTAINS. Postgres-fuldtekst bruger i stedet GIN på tsvector.
Oracle-indeks der gemmer én bitmap pr. distinkt værdi. Hver bit markerer én række.
Brug på kolonner med lav kardinalitet i læsetunge warehouses. Samtidige skrivninger serieliseres pr. bitmap.
Indekskolonne erklæret DESC. Nøgler for den kolonne gemmes i omvendt rækkefølge.
Nødvendigt til blandede sorteringer som (a ASC, b DESC). Rene DESC-sorteringer kan også læse et normalt indeks baglæns.
MySQL 8-indeks som optimeringen ignorerer. Vedligeholdes stadig ved hver skrivning.
Skjul et indeks, før du dropper det, for at teste effekten. Gør det synligt igen uden genopbygning.
Design
Flerkolonne-indeks. De førende kolonner skal matche filtrenes rækkefølge i forespørgslen.
Sortér efter lighed først, derefter interval. To enkeltindeks'er kan ikke erstatte ét sammensat.
Indeks på et WHERE-prædikat. SQL Server kalder det et filtered index. Dækker kun matchende rækker.
Indexér kun rækker med active='t'. Halverer størrelse og skriveomkostning.
B-tree med ekstra ikke-nøglekolonner tilføjet. Index-only-scanninger undgår heap-opslag.
Tilføj ofte hentede kolonner via INCLUDE. Holder indekset sortérbart.
Indeks der gennemtvinger ingen dubletværdier. Afviser indsættelser der kolliderer.
Brug til naturlige nøgler og en-til-en-begrænsninger. UNIQUE NULL tillader mange NULL.
Indeks bygget på en funktion af kolonner frem for selve kolonnerne.
Indexér lower(email) eller date_trunc('day', created_at). Forespørgslen skal gentage præcis det samme udtryk.
Operatorklasse. Definerer hvordan et indeks sammenligner og gemmer én kolonnes type.
Sæt varchar_pattern_ops til LIKE 'abc%' uden case folding. Standardværdierne passer til lighed og intervaller.
Plan der besvarer en forespørgsel udelukkende fra indekssider. Heappen læses aldrig.
Kræver hver hentet kolonne i indekset eller INCLUDE-listen. Vacuum holder visibility-mappen opdateret.
Fremmednøglekolonner får intet automatisk indeks i den refererende tabel.
Indexér hver FK-kolonne du joiner eller sletter igennem. Cascade-sletninger skanner barnetabellen uden et.
Vedligeholdelse
Planinspektør. Viser sekventielle scanninger, indeksvalg og omkostningsanslag.
Brug EXPLAIN (ANALYZE, BUFFERS). En Seq Scan på en tabel med 10M rækker betyder et manglende indeks.
Udtager prøver af tabelkolonner for at bygge planner-statistik. Histogrammer styrer indeksvalget.
Kør efter masseindlæsning. Forældet statistik giver seq-scanninger på indekserede kolonner.
Hvert indeks tilføjer skriveomkostning. Inserts, updates og deletes betaler pr. indeks.
Drop ubrugte indekser. Følg forbruget i pg_stat_user_indexes.
Postgres-view med forbrug pr. indeks. Tæller scanninger og læste tupler siden statistiknulstillingen.
Filtrér på idx_scan = 0 for at finde ubrugte indekser. Nulstil tællerne med pg_stat_reset().
Bygger et indeks uden at blokere læsninger eller skrivninger. Kræver to tabelscanninger.
Kan ikke køre i en transaktion. En mislykket bygning efterlader et INVALID indeks, der skal droppes.
Fjerner et indeks og frigør dets lager. Tager en eksklusiv lås som standard.
Brug DROP INDEX CONCURRENTLY på travle tabeller. Tjek forbrugsstatistikken inden fjernelse.
Genopbygger et oppustet indeks. Frigør plads fra døde tupler.
Brug REINDEX CONCURRENTLY i produktion. Låse blokerer skrivninger uden det.
Døde tupler og sidehuller der ophobes i MVCC-tabeller og deres indekser.
Mål med pgstattuple. Vacuum ofte; REINDEX når død plads dominerer.
Procentdel af en side der pakkes ved skrivning. Ledig plads opsuger fremtidige updates.
Sænk den til 70-90 på tabeller med mange updates. Fyldte sider tvinger sidesplit.
Omskriver tabellen fysisk sorteret efter et indeks. Engangsoperation.
Parres med BRIN til sorterede blokke. Rækkefølgen opretholdes ikke ved fremtidige skrivninger.