Tips på hur du optimerar SQL Serverns Index
Förord
Alla tips som givs i den här artikeln om Index är menade som generella riktlinjer, och precis som med de flesta riktlinjer så finns det vissa undantag. På grund av det så kan det vara en bra idé att testa olika Indexstrategier för de vanligaste SQL-satserna som körs mot din databas. Endast genom att testa olika strategier för dina SQL-satser så kan du få reda på om din databas är optimerad till fullo. [SQL Server 6.5, 7.0, 2000] Uppdaterad 02-08-02Innehåll
Relaterade artiklar
» Tips på hur du optimerar SQL Serverns Clustrade IndexTips på hur du optimerar SQL Serverns Index
Du bör överväga att Indexera alla kolumner som frekvent accessas av klausulerna WHERE, ORDER BY, GROUP BY, TOP och DISTINCT. Utan ett Index så kommer var och en av dessa operationer att kräva en tabellscan, vilket kan skada prestandan.
Notera ordet ”överväg”. Ett Index som skapas för att höja hastigheten på en specifik SQL-sats kanske inte är det lämpliga Indexet för en annan SQL-sats i samma tabell. Ibland kan du komma att behöva balansera Indexen för att kunna uppnå en acceptabel prestanda för alla de olika SQL-satserna som kör mot en tabell. [SQL Server 6.5, 7.0, 2000] Uppdaterad 01-12-07
*****
Lägg inte automatiskt till Index i en tabell bara för att det verkar vara det enda rätta. Lägg bara till Index till en tabell om du vet att den kommer att användas av de SQL-satser som körs mot tabellen. [SQL Server 6.5, 7.0, 2000]
*****
Som en tumregel så bör alla tabeller ha åtminstone ett Clustrat Index. Generellt sett, men inte alltid, så ska det Clustrade Indexet finnas på en kolumn vars värden ökar monotont, såsom t ex identitetskolumner eller kolumner vars värden ökar – och är unika. I många fall så är primärnyckeln en ideal kolumn för Clustrade Index. Se artikeln ”Tips på hur du optimerar SQL Serverns Clustrade Index” (finns längst upp på sidan) för mer detaljer om Clustrade Index. [SQL Server 7.0, 2000] Inlagd 02-02-07
*****
Point Queries, SQL-satser som returnerar en enda post, är lika snabba som att använda Clustrade eller icke-Clustrade Index. Om du vill skapa ett Index för att återhämta ett enda record, så bör du vid en mer komplicerad SQL-sats överväga att skapa ett icke-Clustrat Index för att spara in på de Clustrade Indexen (du kan bara ha ett). [SQL Server 6.5, 7.0, 2000] Inlagd 02-02-08
*****
För att hjälpa dig identifiera vilka tabeller i din databas som behöver nya eller extra Index, så kan du använda dig utav SQL Server Profiler Create Trace Wizard och sen köra ”Identify Scans of Large Tables”. Den här sökningen kommer att tala om för dig vilka tabeller som söks igenom av SQL-satser istället för att bli igenomsökta av Indexen, för att få fram dina data. Det här bör ge dig användbara data för att hjälpa dig identifiera vilka tabeller som behöver nya eller förbättrade Index. [SQL Server 7.0]
*****
Indexera inte dina OLTP tabeller, eftersom det tar längre tid att utföra dina INSERT, UPDATE eller DELETE operationer för varje Index du lägger till. Det är en tunn gräns mellan att ha en ideal mängd Index (för SELECTs) och det ideala antalet datamodifieringar. [SQL Server 6.5, 7.0, 2000]
*****
Lägg inte till samma Index två gånger i samma tabell av misstag. Det sker mycket lättare än du kan tro. Om du t ex sätter en kolumn som unik eller primär nyckel så skapar du förstås ett Index som framtvingar det du vill ska hända. Men när du granskar behovet av ett nytt Index i en tabell så kan du utan att tänka på det sätta detta nya Index på just den kolumnen som du valde som unik eller primär nyckel. Men så länge som du ger Indexen olika namn så kommer SQL Server att låta dig skapa samma Index om och om igen. [SQL Server 7.0, 2000] Inlagd 01-04-02
*****
Ta bort Index som aldrig används av din Query Optimizer. Oanvända Index saktar ner datamodifikationer, skapar onödiga I/O läsningar när den läser datasidorna, slösar plats i din databas samt ökar den tid det tar för att köra en backup eller återhämta dina databaser. Använd din Index Wizard (i 7.0 och 2000) för att hjälpa dig identifiera vilka Index som inte används. [SQL Server 7.0, 2000] Uppdaterad 02-02-07
*****
Generellt sett så bör du inte lägga till några Index under följande omständigheter:
- Om ett Index inte används av din Query Optimizer. Använd din Query Analyzers alternativ ”Show Execution Plan” för att se om en SQL-sats som körs mot en speciell tabell använder ett Index eller inte. Om det är en liten tabell så är det högst troligt att det inte används något Index.
- Om tabellvärdena visar på låg selektivitet (oftast mindre än 90-95 % för icke-Clustrade Index).
- Om kolumnen (kolumnerna) som ska Indexeras är väldigt breda.
- Om kolumnen (kolumnerna) är definierad som någon av datatyperna TEXT, NTEXT eller IMAGE.
- Om det sällan körs någon SQL-sats mot tabellen.
[SQL Server 6.5, 7.0, 2000] Uppdaterad 00-10-05
*****
Trots att hög Indexselektivitet generellt sett är en viktig faktor för att din Query Optimizer ska kunna se huruvida en SQL-sats är användbar eller inte, så finns det faktiskt ett speciellt fall där Index av låg selektivitet kan vara användbart för att höja hasigheten på SQL Server. Det handlar om Index med externa nycklar. Vare sig ett Index på en extern nyckel har en hög eller låg selektivitet, så kan ett Index på en extern nyckel användas av Query Optimizer för att utföra en Merge Join på tabellerna i fråga. En Merge Join uppstår då man tar en post från varje tabell och jämförs för att se om de matchar den specifika Join kriterian. Så länge som de JOINade tabellerna har de lämpliga Indexen (oavsett selektivitet) så kan en Merge Join utföras, vilket generellt sett är mycket snabbare än att JOINa tabeller med externa nycklar som inte något Index. [SQL Server 7.0, 2000] Inlagd 01-04-09.
*****
Det är normalt sett inga problem att ha så många Index som behövs för att täcka virtuellt sett vilken SQL-sats som helst i datalagringsdatabaser (som vanligtvis är read-only). [SQL Server 6.5, 7.0, 2000]
*****
För att kunna förse din Query Optimizer med den senaste uppdaterade statistiken som den behöver för att kunna göra smarta val vid optimering av SQL-satser, så bör du generellt sett hålla databasalternativet ”Auto Update Statistics” aktiverat. Det hjälper dig att försäkra dig om att optimeringsstatistiken är giltig, samt försäkrar dig om att SQL-satserna är optimerade ordentligt när de körs.
Men det här alternativet är inte lösningen. När en SQL Server databas är väldigt sysselsatt så kan ”Auto Update Statistics” alternativet välja att uppdatera statistiken vid olämpliga tillfällen, som t ex den mest sysselsatta tidpunkten på dagen.
Om du märker att ”Auto Update Statistics” funktionen körs under olämpliga tillfällen på dagen så kan du välja att stänga av alternativet, och sedan uppdatera statistiken manuellt (genom att använda UPDATE STATISTICS eller sp_updatestats) vid tillfällen då databasen inte är lika sysselsatt.
Men fundera då på vad som kommer att hända om du stänger av funktionen. Medan du genom att stänga av funktionen kan reducera den stress som uppstår på Servern då inte funktionen körs vid olämpliga tillfällen, så kan det också leda till att de SQL-satser som körs inte blir ordentligt optimerade – vilket även det kan leda till stress på Servern under sysselsatta tidpunkter på dagen.
Precis som med de flesta andra optimeringsproblem så kan du behöva experimentera dig fram för att se vilket som är bäst i just din miljö – då funktionen är avstängd eller aktiverad. Men som en tumregel gäller det att om din Server inte är helt uttröttad så bör du lämna funktionen. [SQL Server 7.0, 2000]
*****
Håll ”bredden” på dina Index så smala som möjligt. Det reducerar både storleken på Indexet samt reducerar de antalet disk I/O läsningar som krävs för att kunna läsa Indexet, vilket höjer prestandan. [SQL Server 6.5, 7.0, 2000]
*****
Om det är möjligt så bör du skapa Index på kolumner som innehar numeriska värden istället för teckenvärden. Numeriska värden kräver mindre arbetslast än teckenvärden. [SQL Server 6.5, 7.0, 2000]
*****
Om du har två eller fler tabeller som JOINas ihop väldigt ofta, så bör de kolumner som används för JOINerna ha de korrekta Indexen. Om de kolumner som används i JOINerna inte är naturligt kompakta så bör du överväga att lägga till surrogatnycklar till de tabeller som är kompakta. Det bör du göra för att kunna reducera storleken på nycklarna och därmed minska den I/O last som krävs under JOIN processerna, vilket höjer prestandan. [SQL Server 6.5, 7.0, 2000]
*****
När du skapar Index så bör du göra Indexen unika – om det överhuvudtaget går. SQL Server kan oftast söka igenom ett unikt Index mycket snabbare än ett Index som inte är unikt. Det beror på att i ett unikt Index så är varje post unik, och när SQL Server väl har funnit ett värde så behöver den inte söka vidare. [SQL Server 6.5, 7.0, 2000] Inlagd 00-10-19.
*****
Om en specifik SQL-sats som körs mot en tabell inte körs frekvent, och då du lägger till ett Index både kan höja SQL-satsens prestanda samtidigt som du kan påverka operationer som INSERTs, UPDATEs och DELETEs negativt. Då bör du överväga att sätta till ett Index till en tabell medan SQL-satsen körs och sedan ta bort det Indexet. Ett exempel på det är när de månatliga rapporterna körs i slutet på månaden i en OLTP applikation. [SQL Server 6.5, 7.0, 2000] Inlagd 00-09-11.
*****
Om du skulle vilja titta under ytan på SQL Server för att lära dig mer om Indexering, så kan du ta en titt på systemtabellen SysIndex som finns i varje databas. Här kan du finna en hel del information om de Index och tabeller som finns i din databas. För att kunna se över data från den här tabellen så skriver du den här frågan: SELECT * FROM sysindexes från den databasen som du är intresserad av. Här följer några intressanta fält som du kan finna i den här tabellen:
- dpages: Om “indid” värdet är 0 eller 1, så är dpages det antal datasidor som används av Indexet. Om ”indid” värdet är 255, så är dpages lika med noll. I alla andra fall så är dpages antalet icke-Clustrade Indexsidor som används i Indexet.
- Id: Refererar till det ID på tabellen som det här Indexet hör till.
- Indid: Den här kolumnen indikerar på typen av Index. 1 är t ex en Clustrad tabell, ett värde större än 1 är en icke-Clustrad tabell, och 255 indikerar på att tabellen innehåller text- eller bilddata.
- OrigFillFactor: Det här är originalfyllfaktorn som användes då Indexet skapades, men det är inte kvar med tiden.
- Statversion: Följer med det antalet gånger som statistiken har blivit uppdaterad.
- Status: 2 = Unikt Index. 16 = Clustrat Index. 64 = Index som tillåter duplicerade poster. 2048 = Indexet används för att tvinga fram en Primärnyckeln begränsning. 4096 = Indexet används för att tvinga fram en Unik begränsning. Dessa värden är adderbara, så det värde du ser i den här kolumnen kan vara en addition av två eller flera av dessa värden.
- Used: Om “indid” värdet är 0 eller 1, så är Used det totala antalet sidor som används för alla Index- eller tabelldata. Om ”indid” värdet är 255, så är Used det antalet sidor som används för text- eller bilddata. I alla andra fall så är Used det antalet sidor som finns i Indexet.
[SQL Server 7.0, 2000] Inlagd 00-09-08
*****
Använd inte datatyperna FLOAT eller REAL för primärnycklar, eftersom de kräver extra arbetslast och kan skada prestandan. [SQL Server 6.5, 7.0, 2000] Inlagd 00-10-04.
*****
Om du vill höja prestandan i SQL-satser som inkluderar en AND operator i WHERE klausulen, så bör du överväga följande:
- Åtminstone en av sökkriterierna i WHERE klausulen bör vara baserat på en kolumn med hög selektivitet och med ett Index.
- Om åtminstone en av sökkriterierna i WHERE klausulen inte är högt selektiv, så bör du överväga att lägga till ett Index på alla de kolumner som refereras till i WHERE klausulen.
- Om ingen av kolumnerna i WHERE klausulen är selektiva nog för att kunna ha ett eget Index, så bör du överväga att skapa ett täckande Index för den här SQL-satsen.
[SQL Server 7.0, 2000] Uppdaterad 02-02-08.
*****
Din Query Optimizer kommer alltid att utföra en tabellscan, eller en scan över ett Clustrat Index i tabellen, om WHERE klausulen i en SQL-sats innehåller en OR operator och om någon av kolumnerna som refereras till i OR klausulen inte har något Index (eller om de inte har något användbart Index). På grund av det så bör du (om du har många SQL-satser med OR klausuler) försäkra dig om att alla kolumner som refereras till i en WHERE klausul har ett Index. [SQL Server 7.0, 2000] Inlagd 00-10-17.
*****
En SQL-sats som har en eller flera OR klausuler kan ibland skrivas om till en serie av SQL-satser sammankopplade med ett UNION uttryck, för att kunna höja SQL-satsens prestanda. Titta t ex på följande SQL-sats:
SELECT employeeID, firstname, lastname
FROM names
WHERE dept = 'prod' or city = 'Orlando' or division = 'food'
Den här SQL-satsen har tre separata villkor i WHERE klausulen. För att den här SQL-satsen ska kunna använda sig utav ett Index så måste det finns ett Index på alla tre kolumner som finns i WHERE klausulen.
Samma SQL-sats kan skrivas om genom att använda UNION istället för OR, som följande exempel:
SELECT employeeID, firstname, lastname FROM names WHERE dept = 'prod'
UNION
SELECT employeeID, firstname, lastname FROM names WHERE city = 'Orlando'
UNION
SELECT employeeID, firstname, lastname FROM names WHERE division = 'food'
Var och en av dessa SQL-satser kommer att producera samma resultat. Om det bara finns ett Index på ”dept” och inte på någon av de andra kolumnerna, så kommer det första exemplet inte att använda sig av något Index, utan kommer istället att genomföra en tabellscan. I det andra exemplet däremot så kommer SQL-satsen att använda sig av Indexet i en del av SQL-satsen, men inte i hela.
Jag erkänner att det är ett ganska simpelt exempel, men trots det så demonstrerar den ganska väl hur en omskrivning av en SQL-sats kan påverka huruvida ett Index används eller inte. Om den här SQL-satsen hade varit lite mer komplicerad så hade användandet av UNION varit mer effektiv. Det beror på att du skulle kunna optimera varje del i Indexet individuellt, något du inte skulle kunna göra genom att bara använda ORs i din SQL-sats.
Om du har en SQL-sats som använder ORs och som inte använder sig av något Index, överväg då att skriva om den till en UNION sats och testa sedan prestandan. Du kan enbart genom tester avgöra om en version av en SQL-sats presterar snabbare än någon annan. [SQL Server 7.0, 2000] Inlagd 02-02-08.
*****
Din Query Optimizer konverterar en IN klausulen i en Transact-SQL kod till en OR operator då du analyserar din kod. På grund av det så bör du komma ihåg att om en kolumn som det refereras till i din SQL-sats inte inkluderar ett Index, så kommer din Query Optimizer att utföra en tabellscan eller en scan på Clustrade Index mot tabellen. [SQL Server 6.5, 7.0, 2000] Inlagd 00-10-17.
*****
Om du använder dig av SOUNDEX funktionen mot en tabellkolumn i en WHERE klausul, så kommer din Query Optimizer att ignorera alla tillgängliga Index och kommer istället att utföra en tabellscan. Om din tabell då är väldigt så kommer det att medföra ett enormt prestandaproblem. Om du behöver utföra sökningar med hjälp av SOUNDEX funktionen så finns det ett sätt att komma runt det här problemet. Du kan förkalkylera SOUNDEX koden för den kolumnen som du ska söka i och därefter placera dessa värden i en egen kolumn, då kan du sätta till ett Index till den kolumnen för att kunna höja hastigheten på sökningarna. [SQL Server 6.5, 7.0, 2000] Inlagd 00-11-09.
*****
Om du behöver skapa Index på stora tabeller så kan du snabba på skapandet av dem genom att använda dig utav det nya alternativet SORT_IN_TEMPDB, som finns tillgängligt tillsammans med kommandot CREATE INDEX. Det här alternativet talar om för SQL Server att använda tempdb databasen (istället för den aktuella databasen) för att sortera data medan ett Index skapas. Förutsatt att din tempdb databas ligger isolerad på en egen separat hårddisk eller diskarray, så kan man snabba på processen med att skapa Indexet. Det enda negativa med att använda det här alternativet är att den tar upp lite mer plats på hårddisken än om du inte använde det, men i de flesta fall så bör inte detta vara något problem. Om din tempdb databas inte ligger på en separat hårddisk eller diskarray så bör du inte använda det här alternativet, eftersom det då faktiskt kan sänka prestandan. [SQL Server 2000] Inlagd 00-10-19.
*****
SQL Server 2000 Enterprise Edition (inte standardutgåvan) erbjuder förmågan att skapa Index parallellt, vilket kan höja hastigheten på att skapa Index dramatiskt. Förutsatt att din Server har flertalet CPUn så använder SQL Server 2000 en närapå linjär skalning för att höja hastigheten vid skapning av Index. Om du t ex har två CPUn istället för en enda CPU, så kan du närapå halvera den tid det tar för att skapa Index. [SQL Server 2000] Inlagd 00-12-19.
*****
Som du förmodligen redan vet så är Index med smala kolumner att föredra över Index med breda kolumner. Ju smalare ett Index är, desto fler kan SQL Server få plats med på en datasida. Det leder till att det krävs mindre I/O för att kunna komma åt datan på sidorna. Men ibland kan de kolumner som du vill utföra en sökning på med hjälp av ett Index dock vara bredare än önskvärt.
Låt oss t ex säga att du har en musikdatabas där du listar över 5 000 000 sångtitlar, och att du då vill göra en sökning på sångtitlarna. Låt oss också anta att den kolumnen som lagrar sångtitlarna är av datatypen VARCHAR(45). Fyrtifem tecken ger ett väldigt brett Index, och det är därmed inte någon smart idé att skapa något Index på den kolumnen (om man ser det ur prestandans synvinkel). Så hur ska vi hantera ett sådan scenario?
*****
SQL Server 2000 erbjuder nu en ny funktion som kallas CHECKSUM. Huvudsyften med den här funktionen är att skapa det vi kallar ”hash indices”. Ett Hash Index är ett Index som bygger på en kolumn som lagrar Checksumman av de data som vi kan hitta i en annan kolumn i tabellen. Funktionen CHECKSUM tar data från en annan kolumn och skapar ett CHECKSUM värde. Med andra ord så används funktionen CHECKSUM för att skapa det mest unika värdet som representerar andra data i din tabell. I de flesta fall så kommer CHECKSUM värdet att bli mycket mindre än det aktuella värdet. Oftast så är CHECKSUM värdena unika, men det är inte garanterat. Det är möjligt att två värden som skiljer sig lite från varandra, kan producera samma identiska CHECKSUM värde.
Vi kan använda exemplet med musikdatabasen för att se hur detta fungerar. Säg att vi har en sångtitel ”My best friend is a Mule from Missouri” (”Min bästa vän är en Mula från Missouri”). Som du kan se så är det en ganska lång sångtitel, och att Indexera kolumnen med sångtitlar skulle skapa ett väldigt brett Index. Men i samma tabell så kan vi lägga till en CHECKSUM kolumn som tar sångtiteln och skapar en Checksumma baserat på den. I det här fallet så skulle Checksumman bli 1866876339. Funktionen CHECKSUM fungerar alltid på samma sätt, så om du skulle utföra CHECKSUM funktionen på samma värde flera gånger så skulle du alltid få samma resultat.
Så hur kan CHECKSUM hjälpa oss? Fördelen med CHECKSUM funktionen är att istället för att vi skapar ett brett Index baserat på kolumnen med sångtitlar, så skapar vi ett Index på CHECKSUM kolumnen. ”Okej, det är finfint, men jag trodde att vi skulle göra sökningar på sångtitlarna! Hur kan någon ens hoppas på att komma ihåg ett CHECKSUM värde att göra en sökning på?”
Så här. Ta en stund på dig för att granska koden:
SELECT title, artist, composer
FROM songs
WHERE title = 'My Best Friend is a Mule from Missouri'
AND checksum_title = CHECKSUM('My Best Friend is a Mule from Missouri')
I det här exemplet så verkar det som om vi har ställt samma fråga två gånger, och det har vi på sätt och vis. Anledningen till att vi måste göra så här är att det kan finnas två CHECKSUM värden som är identiska trots att inte sångtitlarna är det. Kom ihåg att man inte kan garantera unika CHECKSUM värden.
Så här funkar SQL-satsen. När din Query Optimizer granskar WHERE klausulen så ser den om det finns något Index satt på kolumnen Checksum_title. Och på grund av att Checksum_title kolumnen är högt selektiv (få duplicerade värden) så väljer Query Optimizern att använda sig utav Indexet. Dessutom så kan även Query Optimizern använda sig utav CHECKSUM funktionen och kan därmed konvertera sångtitlarna till Checksum värden. Detta värde använder den sig sedan av för att lokalisera de matchande recorderna i Indexet. Tack vare att ett Index används så kan SQL Server snabbt lokalisera de poster som matchar den andra delen i WHERE klausulen. När posterna väl har minskats ner av Indexet så är det enda som kvarstår att jämföra de matchande posterna med den första delen i WHERE klausulen, vilket inte kommer att ta så lång tid.
Det verkar som om det är en hel del jobb att utföra för att kunna minska ner bredden i ett Index, men i många fall så kommer detta att belöna sig med bättre prestanda i längden. På grund av det här tipsets natur så föreslår jag att du experimenterar med hjälp av den här metoden, jämfört med de mer konventionella metoderna för att kunna skapa ett Index på en kolumn själv. På grund av de olika variablerna att överväga så kan det vara svårt att veta vilken av metoderna som passar i just din situation, om du inte ger de båda ett försök. [SQL Server 2000] Inlagd 01-03-06.
*****
Vissa SQL-satser kan vara väldigt komplicerade och inkludera flera tabeller, JOINs och andra villkor. Jag har sett SQL-satser som kör över 1 000 rader av kod (jag har inte skrivit dem). Det kan göra de svåra att analysera för att få reda på vilka Index som skulle kunna användas för att hjälpa SQL-satsen att prestera bättre.
Du kanske t ex vill skapa ett täckande Index för en SQL-sats och du vill kunna identifiera de kolumner som ska inkluderas i det täckande Indexet. Eller du kanske vill kunna identifiera JOINade kolumner för att se om du har Indexerat dessa kolumner, för att ha maximal prestanda.
För att göra komplicerade SQL-satser lättare att analysera så bör du överväga att bryta ner dem till dess mindre beståndsdelar. Ett sätt att göra det på är genom att helt enkelt lista upp huvudkomponenterna i SQL-satsen, som t ex:
- Lista alla de kolumner som ska returneras
- Lista alla de kolumner som används i WHERE klausulen
- Lista alla de kolumner som används i JOINerna (om det går)
- Lista alla de tabeller som används i JOINerna (om det går)
När du väl har organiserat i ordning ovanstående information i detta lättförståeliga format, så är det mycket lättare att se de kolumner som eventuellt skulle använda sig utav Index då den exekveras. [SQL Server 6.5, 7.0, 2000] Inlagd 02-02-08
*****
SQL-satser som inkluderar något av DISTINCT eller GROUP BY klausulerna kan optimeras genom att använda lämpliga Index. Du kan använda dig utav någon av följande Indexstrategier:
- Inkludera ett täckande, icke-Clustrat Index (som täcker de lämpliga kolumnerna) i DISTINCT eller GROUP BY klausulerna.
- Inkludera ett Clustrat Index på kolumnerna i GROUP BY klausulen.
- Inkludera ett Clustrat Index på kolumnerna funna i SELECT klausulen.
Att lägga till ett lämpligt Index i SQL-satser som inkluderar DISTINCT eller GROUP BY klausuler är viktigast för sådana SQL-satser som körs ofta. Om en SQL-sats sällan körs så kan nog skapa istället för att förhindra prestandaproblem, om du lägger till ett Index. [SQL Server 7.0, 2000] Inlagd 02-03-08.
*****
Beräknade kolumner i SQL Server 2000 kan Indexeras om de möter ALLA följande kriterier:
- Om den beräknade kolumnens uttryck är bestämbart. Det innebär att de beräknade värdena alltid måste vara av samma givna inputs.
- Om ANSI_NULL objektets anslutningsnivå fanns på när tabellen skapades.
- Om datatyperna TEXT, NTEXT eller IMAGE inte används i den beräknade kolumnen.
- Om den fysiska anslutningen som krävs för att skapa Indexen, samt om alla anslutningar som finns till INSERT, UPDATE eller DELETE posterna har följande sex SET alternativ konfigurerade korrekt: ANSI_NULLS = ON, ANSI_PADDINGS = ON, ANSI_WARNINGS = ON, ARITHABORT = ON, CONCAT_NULL_YIELDS_NULL = ON, QUOTED_IDENTIFIER = ON, NUMERIC_ROUNDABORT = OFF.
Om du skapar ett Clustrat Index på en beräknad tabell så kommer de beräknade värdena att lagras i den tabellen, precis som med vilket annat Clustrat Index som helst. Om du skapar ett icke-Clustrat Index så kommer de beräknade värdena att lagras i Indexet, och inte i själva tabellen.
Trots att det går att Indexera en beräknad kolumn, så är det inte alltid rekommenderat. Det största problemet med att göra det är att om värdena i den beräknade kolumnen ändras, så måste även Indexet (Clustrat eller icke-Clustrat) uppdateras, vilket leder till extra arbetslast. Om det är många beräknade värden som ändras så kan den extra arbetslasten skapa prestandan betydligt.
Den vanligaste anledningen till att du bör överväga att skapa ett Index på en beräknad kolumn är om du använder CHECKSUM() funktionen på en stor teckenkolumn, för att reducera storleken på ett Index. På du använder CHECKSUM() funktionen på en stor teckenkolumn och Indexerar den kolumnen istället för själva teckenkolumnen, så kan du reducera storleken på Indexet och därmed spara plats på hårddisken och höja prestandan. [SQL Server 2000] Uppdaterad 02-08-13.
*****
Många databaser råkar ut för både OLTP- och DSS SQL-satser. Som du förmodligen redan vet så är det närapå omöjligt att optimera Indexeringen i en databas som hanterar båda typerna av dessa SQL-satser. Det beror på att för att SQL-satserna för OLTP ska vara snabba så bör det inte finnas så många Index som kan hindra INSERT-, UPDATE- och DELETE operationer. Och när det gäller hastigheten på SQL-satser för DSS så bör det helst finnas så många Index som behövs för att snabba på SELECT satserna.
Trots att det finns många olika vägar att gå för att hantera det här dilemmat så finns det ett speciellt alternativ som funkar för många människor. Det är en strategi där DSS satser för det mesta (om inte alltid) körs efter arbetstid (om det finns någon ”efter arbetstid” för din databas), och sen drar fördel av de Index som skapas varje natt innan DSS satserna körs, för att sedan ta bort dem när DSS satserna har avslutats. På så sätt så kommer OLTP transaktionerna (speciellt under sysselsatta tidpunkter på dagen) att störas minimalt av de Index som behövs för att DSS satserna ska kunna prestera snabbt.
Som du kanske kan förstå så kräver den här strategin en del planering och arbete, men i de flesta fall så kan strategin erbjuda den bästa prestandan för databaser som utsätts för både OLTP- och DSS satser. På grund av att det är svårt att gissa sig fram om den här strategin skulle fungera för just dig, så bör du testa dig det här innan du sätter detta i produktion.
0 Kommentarer