sql >> Database >  >> RDS >> Database

Database-optimalisatie:indexen

Ik heb gemerkt dat maar heel weinig mensen begrijpen hoe indexen werken in SQL Server, met name opgenomen kolommen. Niettemin zijn indexen de geweldige manier om zoekopdrachten te optimaliseren. In het begin kreeg ik ook niet het idee van de opgenomen kolommen, maar mijn experimenten toonden aan dat ze erg nuttig zijn.

Stel dat we de volgende tabel en query hebben:

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'

Het is duidelijk dat PersonID een primaire sleutel is. Stel dat we een index hebben met de voor- en achternaam, laten we deze IX_Person_FirstNameLastName noemen. Het uitvoeringsplan voor een dergelijke zoekopdracht ziet er als volgt uit:

  1. Alle regels met de opgegeven voor- en achternaam vinden met behulp van de indexstructuur IX_Person_FirstNameLastName
  2. De werkelijke locatie van de regel op de schijf op de indexbladeren detecteren, naar de werkelijke locatie gaan en de leeftijd lezen.

Laten we er nu eens van uitgaan dat deze query vrij vaak wordt uitgevoerd. We moeten telkens 2 stappen uitvoeren. Kan het geoptimaliseerd worden? In het geval van MS SQL Server is dat geen probleem - u kunt waarden rechtstreeks in de index opnemen met behulp van de optie INCLUDE.

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

Dit veld wordt nu niet gebruikt tijdens het indexeren, maar is opgenomen in de index. Welke problemen kunnen we daarbij tegenkomen? Wanneer we een tabel indexeren op een bepaald veld, moet de databaseserver een indexstructuur bouwen op basis van dit veld. Dit betekent dat we de indexboom moeten wijzigen bij het wijzigen van de waarde. Wanneer waarden intensief worden gewijzigd, wordt het een problematische en zware taak voor de server. Wanneer het updaten te omvangrijk wordt, is het soms gemakkelijker om de index te laten vallen. Index optimaliseert de zoekactie aanzienlijk, maar heeft een negatieve invloed op de bewerkingen voor invoegen, verwijderen en bijwerken.
Als een veld gewoon in een index wordt opgenomen, wordt het niet gebruikt tijdens het bouwen van een indexstructuur en heeft het geen invloed op het veld. waarde is gemakkelijk terug te vinden op het blad van deze boom. Wanneer er op de voor- en achternaam wordt gezocht, zoekt de server naar alle voor- en achternaam van de boom, en wanneer deze het blad bereikt (vindt de vereiste indexwaarde), dan naast de aanwijzer naar de fysieke locatie van de regelwaarden bevat het ook veldwaarden die in de index zijn opgenomen. Het betekent dat het niet nodig is om de tweede stap te nemen om over te schakelen naar de fysieke locatie van de lijn en deze vanaf daar te lezen.

Aangezien u de boomstructuur niet hoeft te wijzigen bij het wijzigen van de leeftijdsgegevens, heeft dit alles niet veel invloed op de bewerkingen voor het wijzigen van gegevens. We hoeven de index niet te wijzigen, we hoeven alleen de waarden op het boomblad te wijzigen. Dat is de reden waarom zelfs een enorme verandering van het Age-veld geen grote invloed zal hebben op de prestaties. Het zal zeker invloed hebben, maar niet zo veel.

Voor zover ik weet, worden de waarden van de geclusterde index automatisch opgenomen in het bladniveau, maar dit moet worden gecontroleerd met de specificatie.

Dus, wanneer het gebruik van de opgenomen velden voordelig is? Wanneer ze vaak worden gebruikt in zoekopdrachtresultaten, maar af en toe worden gewijzigd. Een voorbeeld is een tabel met banktransacties. Zo'n tabel kan uit de volgende velden bestaan:rekeningnummer, transactietype, datum, bedrag. Het heeft geen zin om te indexeren op som, maar we kunnen het in de index opnemen en het zal de zoekopdracht aanzienlijk versnellen.

Om het echte effect van indexering te achterhalen, moeten de query's niet alle velden selecteren, d.w.z. we moeten de tabel SELECT * FROM vergeten. Bereken altijd alleen de velden die u echt nodig heeft. En als hun waarden in de index komen te staan, kan de uitvoeringssnelheid behoorlijk hoog zijn.

Handig hulpmiddel:

dbForge Index Manager – handige SSMS-invoegtoepassing voor het analyseren van de status van SQL-indexen en het oplossen van problemen met indexfragmentatie.


  1. hoe de rijgrootte in de tabel te vinden

  2. Een weergave gebruiken zonder primaire sleutel met Entiteit

  3. SQL-fout:ORA-02291:integriteitsbeperking

  4. Entity Framework Core 2.0:de abstracte basisklasse eenmalig configureren