Databaseindekser bruges til at forbedre hastigheden af databaseoperationer i en tabel med et stort antal poster. Databaseindekser (både klyngede indekser og ikke-klyngede indekser) ligner meget bogindekser i deres funktionalitet. Et bogindeks giver dig mulighed for at gå direkte til de forskellige emner, der diskuteres i bogen. Hvis du vil søge på et bestemt emne, går du bare til indeks, finder det sidetal, der indeholder det emne, du leder efter og kan derefter gå direkte til den side. Uden et indeks ville du skulle søge i hele bogen.
Databaseindekser fungerer på samme måde. Uden indekser ville du skulle søge i hele tabellen for at udføre en specifik databaseoperation. Med indekser behøver du ikke at scanne gennem alle tabelposter. Indekset peger dig direkte på den post, du søger efter, hvilket reducerer din forespørgsels eksekveringstid betydeligt.
SQL Server-indekser kan opdeles i to hovedtyper:
- Klyngede indekser
- Ikke-klyngede indekser
I denne artikel vil vi se på, hvad klyngede og ikke-klyngede indeks er, hvordan de er oprettet, og hvad de vigtigste forskelle mellem de to er. Vi vil også se på, hvornår man skal bruge klyngede eller ikke-klyngede indekser i SQL Server.
Lad os først starte med et klynget indeks.
Clustered Index
Et clustered index er et indeks, som definerer den fysiske rækkefølge, som tabelposter lagres i i en database. Da der kun kan være én måde, hvorpå poster fysisk lagres i en databasetabel, kan der kun være ét klynget indeks pr. tabel. Som standard oprettes et klynget indeks på en primær nøglekolonne.
Standard Clustered Indexes
Lad os oprette en dummy-tabel med primær nøglekolonne for at se standardklyngeindekset. Udfør følgende script:
CREATE DATABASE Hospital
CREATE TABLE Patients
(
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
gender VARCHAR(50) NOT NULL,
age INT NOT NULL
)
Ovenstående script opretter en dummy-database Hospital. Databasen har 4 kolonner:id, navn, køn, alder. Id-kolonnen er den primære nøglekolonne. Når ovenstående script udføres, oprettes der automatisk et klynget indeks på id-kolonnen. For at se alle indekserne i en tabel kan du bruge den lagrede procedure "sp_helpindex".
USE Hospital
EXECUTE sp_helpindex Patients
Her er outputtet:
Du kan se indeksnavnet, beskrivelsen og kolonnen, som indekset er oprettet på. Hvis du tilføjer en ny post til tabellen Patienter, vil den blive gemt i stigende rækkefølge efter værdien i id-kolonnen. Hvis den første post, du indsætter i tabellen, har et id på tre, vil posten blive gemt i den tredje række i stedet for den første række, da det klyngede indeks opretholder den fysiske orden.
Tilpassede grupperede indekser
Du kan oprette dine egne klyngede indekser. Men før du kan gøre det, skal du oprette det eksisterende klyngeindeks. Vi har et klynget indeks på grund af den primære nøglekolonne. Hvis vi fjerner den primære nøglebegrænsning, vil standardklyngen blive fjernet. Følgende script fjerner den primære nøglebegrænsning.
USE Hospital
ALTER TABLE Patients
DROP CONSTRAINT PK__Patients__3213E83F3DFAFAAD
GO
Følgende script opretter et tilpasset indeks "IX_tblPatient_Age" i alderskolonnen i tabellen Patienter. På grund af dette indeks vil alle posterne i patienttabellen blive gemt i stigende rækkefølge efter alder.
use Hospital
CREATE CLUSTERED INDEX IX_tblPatient_Age
ON Patients(age ASC)
Lad os nu tilføje et par dummy-poster i patienttabellen for at se, om de faktisk er indsat i stigende aldersrækkefølge:
USE Hospital
INSERT INTO Patients
VALUES
(1, 'Sara', 'Female', 34),
(2, 'Jon', 'Male', 20),
(3, 'Mike', 'Male', 54),
(4, 'Ana', 'Female', 10),
(5, 'Nick', 'Female', 29)
I ovenstående script tilføjer vi 5 dummy-records. Læg mærke til værdierne for alderskolonnen. De har tilfældige værdier og er ikke i nogen logisk rækkefølge. Men da vi har oprettet et klynget indeks, vil posterne faktisk blive indsat i stigende rækkefølge af værdien i alderskolonnen. Du kan bekræfte dette ved at vælge alle journalerne fra tabellen Patienter.
SELECT * FROM Patients
Her er outputtet:
Du kan se, at poster er ordnet i stigende rækkefølge af værdierne i alderskolonnen.
Ikke-klyngede indekser
Et ikke-klynget indeks bruges også til at fremskynde søgeoperationer. I modsætning til et klynget indeks definerer et ikke-klynget indeks ikke fysisk rækkefølgen, hvori poster indsættes i en tabel. Faktisk er et ikke-klynget indeks gemt på en separat placering fra datatabellen. Et ikke-klynget indeks er ligesom et bogindeks, som er placeret adskilt fra bogens hovedindhold. Da ikke-klyngede indekser er placeret på en separat placering, kan der være flere ikke-klyngede indekser pr. tabel.
For at oprette et ikke-klynget indeks skal du bruge "CREATE NOCLUSTERED"-sætningen. Resten af syntaksen forbliver den samme som syntaksen for oprettelse af et klynget indeks. Følgende script opretter et ikke-klynget indeks "IX_tblPatient_Name", som sorterer posterne i stigende rækkefølge efter navnet.
use Hospital
CREATE NONCLUSTERED INDEX IX_tblPatient_Name
ON Patients(name ASC)
Ovenstående script vil oprette et indeks, som indeholder navnene på patienterne og adressen på deres tilsvarende journaler som vist nedenfor:
Navn | Record-adresse |
Ana | Record-adresse |
Jon | Record-adresse |
Mike | Record-adresse |
Nick | Record-adresse |
Sara | Record-adresse |
Her er "Record-adressen" i hver række referencen til de faktiske tabelposter for patienterne med tilsvarende navne.
Hvis du for eksempel ønsker at hente alder og køn på patienten ved navn "Mike", vil databasen først søge "Mick" i det ikke-klyngede indeks "IX_tblPatient_Name", og fra det ikke-klyngede indeks vil den hente den faktiske postreference og vil bruge det til at returnere den faktiske alder og køn for patienten ved navn "Mike"
Da en database skal foretage to søgninger, først i det ikke-klyngede indeks og derefter i den faktiske tabel, kan ikke-klyngede indekser være langsommere for søgeoperationer. Men for INSERT- og UPDATE-operationer er ikke-klyngede indekser hurtigere, da rækkefølgen af posterne kun skal opdateres i indekset og ikke i den faktiske tabel.
Hvornår skal du bruge grupperede eller ikke-klyngede indekser
Nu hvor du kender forskellene mellem et klynget og et ikke-klynget indeks, lad os se de forskellige scenarier for at bruge hver af dem.
1. Antal indekser
Dette er ret indlysende. Hvis du har brug for at oprette flere indekser på din database, skal du vælge ikke-klyngede indeks, da der kun kan være ét klynget indeks.
2. VÆLG handlinger
Hvis du kun vil vælge den indeksværdi, der bruges til at oprette og indeksere, er ikke-klyngede indekser hurtigere. For eksempel, hvis du har oprettet et indeks i kolonnen "navn", og du kun vil vælge navnet, vil ikke-klyngede indekser hurtigt returnere navnet.
Men hvis du ønsker at vælge andre kolonneværdier såsom alder, køn ved hjælp af navneindekset, vil SELECT-operationen være langsommere, da først navnet vil blive søgt fra indekset og derefter referencen til den faktiske tabelpost vil blive brugt til at søge alder og køn.
På den anden side, med klyngede indekser, da alle poster allerede er sorteret, er SELECT-operationen hurtigere, hvis dataene vælges fra andre kolonner end kolonnen med klynget indeks.
3. INSERT/OPDATERING Operationer
INSERT- og UPDATE-operationerne er hurtigere med ikke-klyngede indekser, da de faktiske poster ikke skal sorteres, når en INSERT- eller UPDATE-operation udføres. Det er snarere kun det ikke-klyngede indeks, der skal opdateres.
4. Diskplads
Da ikke-klyngede indekser gemmes på en separat placering end den oprindelige tabel, bruger ikke-klyngede indekser yderligere diskplads. Hvis diskplads er et problem, skal du bruge et klynget indeks.
5. Endelig dom
Som en tommelfingerregel bør hver tabel have mindst et klynget indeks, fortrinsvis på den kolonne, der bruges til at SELECTERE poster og indeholder unikke værdier. Den primære nøglekolonne er en ideel kandidat til et klynget indeks.
På den anden side bør kolonner, der ofte er involveret i INSERT- og UPDATE-forespørgsler, have et ikke-klynget indeks, forudsat at diskplads ikke er et problem.