Databasindex används för att påskynda olika tabelloperationer. Men innan du skapar ett index är det viktigt att veta om du verkligen behöver ett index? Och om du behöver skapa ett index, vilka är de viktiga punkterna som måste komma ihåg? Det är här databasindexdesign kommer in.
Den här artikeln syftar till att besvara dessa frågor om design av databasindex och kasta lite ljus över några av de viktigaste övervägandena som en databasutvecklare bör ta hänsyn till när han utformar ett index.
1. Tabellstorlek
Den första frågan som en databasutvecklare måste ställa innan man skapar ett index är om tabellen är tillräckligt stor för att effektivt använda index. Om tabellstorleken är liten kan SQL Server-motorn skanna hela tabellen snabbare än att söka i tabellen genom ett index. Index i sådana fall har ingen användning och skapar en overhead när databasoperationer utförs.
2. Kolumntyper
Index bör skapas på en primärnyckelkolumn eller vilken kolumn som helst som innehåller unika värden och som har en NOT NULL-begränsning. Dessutom är det tillrådligt att skapa index på numeriska kolumner eftersom numeriska kolumner tenderar att ha mer unika värden jämfört med icke-numeriska kolumner. Dålig databasindexdesign använder index på kolumner som har väldigt få unika poster och kan resultera i mycket tidskrävande frågor.
Tänk på en tabell med namnet Patienter som innehåller hundratusentals register. Patienttabellen skulle innehålla en kolumn som heter "Kön" som bara kan ha två unika värden "Man" och "Kvinna". Om du skapar ett index på "Könskolumnen" kommer posterna att sorteras i stigande eller fallande alfabetisk ordning.
Så om du har en miljon poster i patienttabellen och antalet manliga och kvinnliga patienter är lika, i indexet kommer den första halva miljonen poster att ha könet "Kvinna" och den andra halva miljonen kommer att ha kön "Man". Om du nu vill söka efter en hona som finns på den 490 000:e raden av de kvinnliga posterna, måste SQL Server Engine skanna igenom 490 000 poster. Å andra sidan, med unika numeriska värden kan sökningen vara extremt snabb eftersom SQL Server-index lagras i form av B + Trees, och så numeriska värden i trädnoderna kan påskynda databasoperationer.
3. Antal index
Officiellt kan du skapa ett klustrat index och så många icke-klustrade index som du vill för varje databastabell. Det är dock bra databasindexdesign att skapa ett klustrat index och endast ett begränsat antal absolut nödvändiga icke-klustrade index. Att skapa för många icke-klustrade index kan faktiskt sakta ner uppdaterings- och infogningsoperationer eftersom när en post uppdateras eller infogas och ett kolumnvärde ändras måste alla associerade index uppdateras.
Tänk på ett scenario där vi har två icke-klustrade index, det första indexet sorterar posterna efter ålder och det andra indexet sorterar posterna efter både kön och ålder.
Här är det första indexet:
Ålder | Registrera adress |
10 | Registrera adress |
22 | Registrera adress |
29 | Registrera adress |
32 | Registrera adress |
33 | Registrera adress |
36 | Registrera adress |
40 | Registrera adress |
49 | Registrera adress |
54 | Registrera adress |
59 | Registrera adress |
Och här är den andra:
Kön | Ålder | Rekordsadress |
Kvinna | 10 | Registrera adress |
Kvinna | 29 | Registrera adress |
Kvinna | 33 | Registrera adress |
Kvinna | 40 | Registrera adress |
Kvinna | 54 | Registrera adress |
Man | 22 | Registrera adress |
Man | 32 | Registrera adress |
Man | 36 | Registrera adress |
Man | 49 | Registrera adress |
Man | 59 | Registrera adress |
Om nu en post med ålder 40 måste uppdateras till ålder 15 av någon anledning, då måste det första indexet uppdateras för att flytta posten från den 7:e positionen(40) till den andra positionen för att hålla indexet sorterat. På samma sätt i det andra indexet kommer posten i 4:e indexet att flyttas till det andra indexet. En hel del omställningar måste ske. Därför är det klokt att hålla antalet index till ett minimum för de kolumner som uppdateras regelbundet när man tänker på databasindexdesign. En kolumn bör inte heller användas i flera icke-klustrade index.
4. Lagringsplats för index
Lagringsplatsen för ett index kan påverka prestandan för de frågor som använder indexet och är därför också en del av bra databasindexdesign. Som standard lagras ett klustrat index i samma filgrupp som tabellen där indexet skapas. För icke-klustrade index kan indexet lagras i samma filgrupp eller i olika filgrupper som spänner över flera diskenheter. Frågeprestanda för icke-klustrade index kan förbättras avsevärt genom att lagra icke-klustrade index på flera diskenheter. Detta beror på att in-/utdataprestandan för frågan kommer att förbättras som ett resultat av att data distribueras på olika områden på enheten.
Standardlagringsplatsen för index kan också ändras genom att ange ett värde för alternativet FILLFACTOR. Eftersom index lagras fysiskt i form av B+-träd, lagras indexdata på bladsidor. Med alternativet FILLFACTOR kan du ställa in hur stor procentandel av sidorna på bladnivå som ska fyllas. Om du till exempel ställer in värdet för FILLFACTOR till 70 %, kommer endast 70 % av det totala utrymmet på bladnivåsidan att fyllas av indexdata. De återstående 30 % kommer att finnas kvar för automatisk tillväxt av indexdata i framtiden.
5. Indextyper
En annan extremt viktig faktor vid design av databasindex är vilken typ av index som ska användas. I en tidigare artikel (lägg till en länk till artikeln "When to use Clustered or Non-Clustered Index") förklarade jag skillnaden mellan klustrade och icke-klustrade index. Jag förklarade också vad de är och hur de kan användas. Beslutet om att välja ett klustrat eller ett icke-klustrat index är avgörande och bör noggrant tänkas igenom.
Följande punkter bör komma ihåg när du bestämmer vilken indextyp du ska välja.
- Använd klustrade index för kolumnerna som används i SELECT/JOIN/GROUP BY/BETWEEN-frågor.
- Använd icke-klustrade index för kolumner där du bara vill hämta värden från den specifika kolumnen och inte från de andra kolumnerna i samma rad. SELECT-frågor som hämtar flera poster med ett icke-klustrat index kan vara långsamma eftersom SQL Server-motorn först söker efter kolumnvärdena som indexet skapas på och sedan med hjälp av radreferensen för kolumnvärdet, hämtas posterna från faktiska databastabeller .
- För de kolumner som ofta genomgår INSERT- och UPDATE-operationer, använd ett icke-klustrat index. Se till att inte använda en kolumn i flera icke-klustrade index eftersom det kan sakta ner uppdateringsfrågor. Klustrade index kan vara långsamma för INSERT/UPDATE-operationer eftersom hela raden måste uppdateras istället för endast ett enda kolumnvärde som är fallet med icke-klustrade index.
- Eftersom du bara kan skapa ett klustrat index, i deras fall där du behöver flera index, använd icke-klustrade index. Men om diskutrymme är ett stort problem, håll antalet icke-klustrade index till ett minimum.
Övriga överväganden
Även om dessa är de fem viktigaste delarna av databasindexdesign är de inte allt. Det är viktigt att ange rätt ordning på kolumnerna i index. Som en tumregel bör kolumnerna som används för beslutsfattande i WHERE-satser, och villkor som större än (>), mindre än (<) etc, placeras före kolumnerna som inte är inblandade i dessa klausuler. I fallet med flera kolumner i WHERE-satsen bör de mest distinkta kolumnnamnen nämnas tidigast i Index-definitionen.
Förutom databasindexdesign spelar frågedesign också en viktig roll för effektiv användning av indexdesign. För optimerat indexunderhåll istället för att skriva flera frågor som fungerar på ett litet antal rader, försök att skriva färre frågor som påverkar ett större antal tabellrader.
Slutsats
Den här artikeln förklarar några av de viktigaste övervägandena som en databasutvecklare måste ta hänsyn till när man tittar på databasindexdesign. Artikeln förklarar också logiken bakom dessa överväganden och innehåller ytterligare förslag för att se till att din databasindexdesign är effektiv.