sql >> Database teknologi >  >> RDS >> Sqlserver

Opret mere end ét ikke-klynget indeks på samme kolonne i SQL Server

Ordene er ret logiske, og du lærer dem ret hurtigt. :)

I lægmandssprog indebærer SEEK, at man opsøger præcise placeringer for poster, hvilket er, hvad SQL-serveren gør, når den kolonne, du søger i, er indekseret, og dit filter (WHERE-tilstanden) er nøjagtig nok.

SCAN betyder et større udvalg af rækker, hvor planlæggeren for udførelse af forespørgsler vurderer, at det er hurtigere at hente en hel række i modsætning til at søge hver værdi individuelt.

Og ja, du kan have flere indekser på samme felt, og nogle gange kan det være en meget god idé. Spil med indekserne og brug planlæggeren for udførelse af forespørgsler til at bestemme, hvad der sker (genvej i SSMS:Ctrl + M). Du kan endda køre to versioner af den samme forespørgsel, og eksekveringsplanlæggeren vil nemt vise dig, hvor mange ressourcer og tid der tager hver, hvilket gør optimering ret let.

Men for at uddybe disse lidt, lad os sige, at du har en adressetabel som sådan, og den har over 1 milliard poster:

CREATE TABLE ADDRESS 
  (ADDRESS_ID INT -- CLUSTERED primary key ADRESS_PK_IDX
  , PERSON_ID INT -- FOREIGN KEY, NONCLUSTERED INDEX ADDRESS_PERSON_IDX
  , CITY VARCHAR(256)
  , MARKED_FOR_CHECKUP BIT
  , **+n^10 different other columns...**)

Hvis du nu vil finde alle adresseoplysningerne for person 12345, er indekset på PERSON_ID perfekt. Da tabellen har masser af andre data i den samme række, ville det være ineffektivt og pladskrævende at oprette et ikke-klynget indeks til at dække alle andre kolonner såvel som PERSON_ID. I dette tilfælde vil SQL Server udføre et indeks SEEK på indekset i PERSON_ID, derefter bruge det til at lave et nøgleopslag på det klyngede indeks i ADDRESS_ID og derfra returnere alle data i alle andre kolonner i den samme række.

Sig dog, at du vil søge efter alle personer i en by, men du behøver ikke andre adresseoplysninger. Denne gang ville den mest effektive måde være at oprette et indeks på CITY og bruge INCLUDE-indstillingen til også at dække PERSON_ID. På den måde ville en enkelt indekssøgning/-scanning returnere alle de oplysninger, du har brug for, uden at du behøver at tjekke CLUSTERED-indekset for PERSON_ID-dataene i samme række.

Lad os nu sige, at begge disse forespørgsler er påkrævet, men stadig temmelig tunge på grund af de 1 milliard poster. Men der er en speciel forespørgsel, der skal være virkelig virkelig hurtig. Denne forespørgsel vil have alle personer på adresser, der er blevet MARKED_FOR_CHECKUP, og som skal bo i New York (ignorer hvad kontrol betyder, det betyder ikke noget). Nu vil du måske oprette et tredje, filtreret indeks på MARKED_FOR_CHECKUP og CITY, med INCLUDE, der dækker PERSON_ID, og ​​med et filter, der siger CITY ='New York' og MARKED_FOR_CHECKUP =1. Dette indeks ville være sindssygt hurtigt, da det kun dækker forespørgsler som opfylder de nøjagtige betingelser og derfor har en brøkdel af dataene at gennemgå sammenlignet med de andre indekser.

(Ansvarsfraskrivelse her, husk på, at planlæggeren for udførelse af forespørgsler ikke er dum, den kan bruge flere ikke-klyngede indekser sammen for at producere de korrekte resultater, så eksemplerne ovenfor er muligvis ikke de bedste tilgængelige, da det er meget svært at forestille sig, hvornår du har brug for 3 forskellige indekser, der dækker den samme kolonne, men jeg er sikker på, at du forstår ideen.)

Indekstyperne, deres kolonner, inkluderede kolonner, sorteringsrækkefølger, filtre osv. afhænger helt af situationen. Du bliver nødt til at lave dækkende indekser for at tilfredsstille flere forskellige typer forespørgsler, såvel som tilpassede indekser, der er oprettet specifikt til enkeltstående, vigtige forespørgsler. Hvert indeks optager plads på harddisken, så det er spild at lave ubrugelige indekser og kræver ekstra vedligeholdelse, hver gang datamodellen ændres, og spilder dog tid på defragmentering og statistikopdatering... så du vil ikke bare smække et indeks på alting enten.

Eksperimenter, lær og find ud af, hvad der passer bedst til dine behov.



  1. GRUPPER EFTER fortløbende datoer afgrænset af huller

  2. ORACLE SQL listegg funktion

  3. Dynamisk revision af data med PostgreSQL trigger

  4. Hvordan grupperer du efter et tidsbaseret interval?