Skip to content

SQL-indeksering forklart

Et jukseark om indekstyper i SQL, designmønstre og vedlikehold.

Indekser bytter lagringsplass og skrivehastighet mot lesehastighet. Velg riktig struktur, avgrens radene, og håndter oppsvulmingen.

Referansetabell · 31 oppføringer
31 of 31 rows
Indekstyper
Balansert tre for likhet, intervall og sorterte søk. Standard i de fleste databaser.Bruk for =, <, >, BETWEEN, ORDER BY. Ikke for fulltekstsøk.
Indeks der bladnivået er selve tabellen. Radene lagres i nøkkelrekkefølge. Én per tabell.InnoDB klynger på primærnøkkelen. SQL Server-tabeller uten en slik er heaps.
Separat struktur med nøkler pluss en peker tilbake til basistabellen. Mange per tabell.På et heap lagrer den en rad-ID. På en klynged tabell lagrer den klyngenøkkelen.
Hashtabell kun for oppslag på likhet. Nøyaktig treff i konstant tid.Bruk kun til =-operasjoner; intervaller og sortering krever B-tree. Hash for minneoptimaliserte SQL Server-tabeller trenger et bucket-antall nær radantallet.
Generalized Inverted Index. Avbilder verdier til rader. Laget for arrays og fulltekst.Bruk for jsonb, arrays, tsvector og trigram-søk. Tregere å bygge enn B-tree.
Generalized Search Tree. Utvidbar for ikke-skalartyper og overlappspørringer.Bruk for geometriske intervaller, kNN og eksklusjonsbegrensninger. pg_trgm gjør LIKE raskere.
Romdelt GiST. Deler data i ikke-overlappende regioner via radix- eller kvadratrær.Bruk for punkter, IP-prefikser og prefikssamsvar. Ikke for overlappspørringer; bruk GiST.
Block Range Index. Lagrer min/maks per blokkintervall. Bittelite fotavtrykk.Bruk på store, fysisk sorterte tabeller. Billig å bygge, svak selektivitet.
Indeks lagret som kolonnesegmenter i stedet for rader. Høy kompresjon, kjøring i batch.Bruk til analytiske skanninger over mange rader og få kolonner. Enkeltrads-oppslag er trege.
Dedikert invertert ordindeks i MySQL og SQL Server. Bygges per tekstkolonne.Bruk MATCH AGAINST eller CONTAINS. Postgres fulltekst bruker GIN på tsvector i stedet.
Oracle-indeks som lagrer én bitmap per distinkt verdi. Hver bit merker én rad.Bruk på kolonner med lav kardinalitet i lesetunge datavarehus. Samtidige skrivinger serialiseres per bitmap.
Indekskolonne deklarert DESC. Nøkler for kolonnen lagres i omvendt rekkefølge.Nødvendig for blandede sorteringer som (a ASC, b DESC). Rene DESC-sorteringer kan også lese en normal indeks baklengs.
MySQL 8-indeks som optimereren ignorerer. Vedlikeholdes fortsatt ved hver skriving.Skjul en indeks før du slipper den, for å teste effekten. Gjør den synlig igjen uten å bygge om.
Design
Flerkolonne-indeks. De ledende kolonnene må samsvare med filterrekkefølgen i spørringen.Sorter med likhet først, deretter intervall. To enkeltindekser kan ikke erstatte én sammensatt.
Indeks på et WHERE-predikat. SQL Server kaller det en filtrert indeks. Dekker kun samsvarende rader.Indekser kun rader med active='t'. Halverer størrelse og skrivekostnad.
B-tree med ekstra ikke-nøkkelkolonner lagt til. Skanninger kun fra indeksen unngår heap-oppslag.Legg til ofte hentede kolonner via INCLUDE. Holder indeksen sorterbar.
Indeks som håndhever fravær av duplikatverdier. Avviser innsettinger som kolliderer.Bruk for naturlige nøkler og én-til-én-begrensninger. UNIQUE med NULL tillater mange NULL-verdier.
Indeks bygget på en funksjon av kolonner, i stedet for selve kolonnene.Indekser lower(email) eller date_trunc('day', created_at). Spørringen må gjenta nøyaktig det samme uttrykket.
Operatorklasse. Definerer hvordan en indeks sammenligner og lagrer typen til én kolonne.Sett varchar_pattern_ops for LIKE 'abc%' uten sammenfolding av store og små bokstaver. Standardklassene passer for likhet og intervaller.
Plan som besvarer en spørring kun fra indekssider. Heapen leses aldri.Krever alle hentede kolonner i indeksen eller INCLUDE-listen. Vacuum holder visibility map oppdatert.
Kolonner med fremmednøkkel får ingen automatisk indeks på den refererende tabellen.Indekser enhver FK-kolonne du kobler eller sletter gjennom. Kaskadesletting skanner barnetabellen uten en.
Vedlikehold
Planinspektør. Viser sekvensielle skanninger, indeksvalg og kostnadsestimater.Bruk EXPLAIN (ANALYZE, BUFFERS). Seq Scan på en tabell med 10 millioner rader betyr manglende indeks.
Tar utvalg av tabellkolonner for å bygge plannerstatistikk. Histogrammer styrer indeksvalget.Kjør etter masselasting. Utdatert statistikk gir seq scans på indekserte kolonner.
Hver indeks legger til skrivekostnad. Inserts, updates og deletes betaler per indeks.Slett ubrukte indekser. Følg bruken i pg_stat_user_indexes.
Postgres-visning av bruk per indeks. Teller skanninger og leste tupler siden statistikken ble nullstilt.Filtrer på idx_scan = 0 for å finne ubrukte indekser. Nullstill tellere med pg_stat_reset().
Bygger en indeks uten å blokkere lesing eller skriving. Krever to tabellskanninger.Kan ikke kjøres i en transaksjon. En mislykket bygging etterlater en INVALID indeks som må slettes.
Fjerner en indeks og frigjør lagringen. Tar en eksklusiv lås som standard.Bruk DROP INDEX CONCURRENTLY på travle tabeller. Sjekk bruksstatistikk før du fjerner.
Bygger om en oppsvulmet indeks. Gjenvinner plass fra døde tupler.Bruk REINDEX CONCURRENTLY i produksjon. Låser blokkerer skriving uten den.
Døde tupler og sidehull som samler seg i MVCC-tabeller og indeksene deres.Mål med pgstattuple. Kjør vacuum ofte; REINDEX når død plass dominerer.
Prosentandel av en side som pakkes ved skriving. Ledig plass tar opp fremtidige oppdateringer.Sett den til 70-90 på tabeller med mange oppdateringer. Fulle sider tvinger frem sidedelinger.
Skriver om tabellen fysisk sortert etter en indeks. Engangsoperasjon.Passer sammen med BRIN for sorterte blokker. Rekkefølgen opprettholdes ikke ved fremtidige skrivinger.