sql >> Databasteknik >  >> RDS >> Database

Databasoptimering:Index

Jag märkte att väldigt få människor förstår hur index fungerar i SQL Server, särskilt Inkluderade kolumner. Ändå är index det utmärkta sättet att optimera frågor. Först fick jag inte heller idén om de inkluderade kolumnerna, men mina experiment visade att de är mycket användbara.

Anta att vi har följande tabell och fråga:

CREATE TABLE Person (
 PersonID int,
 FirstName varchar(100),
 LastName varchar(100),
 Age int,
 …
 …
)

SELECT FirstName, LastName, Age
FROM Person
WHERE FirstName = 'John' and LastName = 'Smith'

Det är tydligt att PersonID är en primärnyckel. Anta att vi har ett index med för- och efternamn, låt oss kalla det IX_Person_FirstNameLastName. Utförandeplanen för en sådan fråga kommer att se ut som följer:

  1. Hitta alla rader med de angivna för- och efternamnen med hjälp av indexträdet IX_Person_FirstNameLastName
  2. Att upptäcka den faktiska platsen för raden på skivan på indexbladen, gå till den faktiska platsen och läsa av åldern.

Låt oss nu tänka på att den här frågan exekveras ganska ofta. Vi måste utföra 2 steg varje gång. Kan det optimeras? I fallet med MS SQL Server är det inget problem – du kan inkludera värden direkt i indexet med hjälp av alternativet INKLUDERA.

CREATE INDEX IX_PERSON ON Person
( 
 FirstName,
 LastName
) 
INCLUDE(Age)

Nu används inte detta fält under indexering utan ingår i indexet. Vilka problem kan vi möta i detta avseende? När vi indexerar en tabell med ett visst fält måste databasservern bygga ett indexträd efter detta fält. Det betyder att vi måste ändra indexträdet när vi ändrar värdet. När värden modifieras intensivt blir det en problematisk och svår uppgift för servern. När uppdateringen blir för omfattande är det ibland lättare att släppa indexet. Index optimerar sökningen avsevärt men påverkar åtgärderna för att infoga, ta bort och uppdatera negativt.
Om ett fält helt enkelt ingår i ett index, används det inte under byggandet av ett indexträd och påverkar inte det, men värde kan lätt hittas på bladet av detta träd. När en sökning på efter- och förnamn sker, söker servern efter alla för- och efternamn från trädet, och när den når bladet (hittar det önskade indexvärdet), sedan utöver pekaren till den fysiska platsen av radvärdena innehåller den även fältvärden som ingår i indexet. Det betyder att det inte finns något behov av att ta det andra steget för att byta till den fysiska platsen för linjen och läsa den därifrån.

Eftersom du inte behöver ändra trädet när du ändrar åldersdata, påverkar allt det här inte mycket dataändringsoperationerna. Vi behöver inte ändra indexet, vi behöver bara ändra värdena på trädbladet. Det är därför inte ens en massiv förändring av åldersfältet kommer att ha någon stor inverkan på prestandan. Det kommer säkert att påverka, men inte så mycket.

Så vitt jag vet ingår värdena för det klustrade indexet automatiskt i bladnivån, men detta måste kontrolleras med specifikationen.

Så när det är fördelaktigt att använda de inkluderade fälten? När de används ofta i frågeresultat men ändras då och då. Ett exempel är en tabell över banktransaktioner. En sådan tabell kan bestå av följande fält:kontonummer, transaktionstyp, datum, summa. Det är ingen idé att indexera med summan, men vi kan inkludera det i indexet och det kommer att påskynda frågan avsevärt.

För att hämta den verkliga effekten från indexering bör frågorna inte välja alla fält, det vill säga vi bör glömma SELECT * FROM-tabellen. Beräkna alltid om bara de fält du verkligen behöver. Och om deras värden kommer att finnas i indexet, kan exekveringshastigheten vara ganska hög.

Användbart verktyg:

dbForge Index Manager – praktiskt SSMS-tillägg för att analysera status för SQL-index och åtgärda problem med indexfragmentering.


  1. Hur fixar jag Microsoft SQL Server Error 926? - Löst

  2. Oracle dokumentation

  3. 5 sätt att kontrollera om en tabell finns i PostgreSQL

  4. Hur man återställer AUTO_INCREMENT i MySQL