sql >> Database >  >> RDS >> Sqlserver

Maak meer dan één niet-geclusterde index op dezelfde kolom in SQL Server

De woorden zijn vrij logisch en je leert ze vrij snel. :)

In termen van leken betekent SEEK het zoeken naar precieze locaties voor records, wat de SQL Server doet wanneer de kolom waarin u zoekt is geïndexeerd en uw filter (de WHERE-voorwaarde) nauwkeurig genoeg is.

SCAN betekent een groter bereik van rijen waarbij de planner voor het uitvoeren van query's schat dat het sneller is om een ​​heel bereik op te halen in plaats van elke waarde afzonderlijk te zoeken.

En ja, je kunt meerdere indexen op hetzelfde veld hebben, en soms kan het een heel goed idee zijn. Speel met de indexen en gebruik de query-uitvoeringsplanner om te bepalen wat er gebeurt (snelkoppeling in SSMS:Ctrl + M). U kunt zelfs twee versies van dezelfde query uitvoeren en de uitvoeringsplanner zal u gemakkelijk laten zien hoeveel middelen en tijd elk van hen in beslag neemt, waardoor optimalisatie vrij eenvoudig wordt.

Maar om hier wat dieper op in te gaan, stel dat u een adrestabel heeft zoals deze, en deze heeft meer dan 1 miljard records:

CREATE TABLE ADDRESS 
  (ADDRESS_ID INT -- CLUSTERED primary key ADRESS_PK_IDX
  , PERSON_ID INT -- FOREIGN KEY, NONCLUSTERED INDEX ADDRESS_PERSON_IDX
  , CITY VARCHAR(256)
  , MARKED_FOR_CHECKUP BIT
  , **+n^10 different other columns...**)

Als u nu alle adresgegevens van persoon 12345 wilt vinden, is de index op PERSON_ID perfect. Aangezien de tabel heel veel andere gegevens op dezelfde rij heeft, zou het inefficiënt en ruimteverslindend zijn om een ​​niet-geclusterde index te maken die alle andere kolommen en PERSON_ID dekt. In dit geval voert SQL Server een index SEEK uit op de index in PERSON_ID, gebruikt dat vervolgens om een ​​sleutelzoekopdracht uit te voeren op de geclusterde index in ADDRESS_ID en retourneert van daaruit alle gegevens in alle andere kolommen op dezelfde rij.

Stel echter dat u wilt zoeken naar alle personen in een stad, maar dat u geen andere adresgegevens nodig heeft. Deze keer zou de meest effectieve manier zijn om een ​​index op CITY te maken en de INCLUDE-optie te gebruiken om ook PERSON_ID te dekken. Op die manier zou een enkele zoek-/scan-index alle informatie opleveren die u nodig hebt zonder dat u de CLUSTERED-index hoeft te controleren op de PERSON_ID-gegevens in dezelfde rij.

Laten we nu zeggen dat beide zoekopdrachten vereist zijn, maar nog steeds vrij zwaar vanwege de 1 miljard records. Maar er is een speciale vraag die echt heel snel moet zijn. Die zoekopdracht wil alle personen op adressen die MARKED_FOR_CHECKUP zijn geweest en die in New York moeten wonen (negeer wat de controle ook betekent, dat maakt niet uit). Nu wil je misschien een derde, gefilterde index maken op MARKED_FOR_CHECKUP en CITY, met INCLUDE voor PERSON_ID, en met een filter met de tekst CITY ='New York' en MARKED_FOR_CHECKUP =1. Deze index zou waanzinnig snel zijn, omdat het alleen zoekopdrachten omvat die aan die exacte voorwaarden voldoen, en daarom een ​​fractie van de gegevens hebben om door te nemen in vergelijking met de andere indexen.

(Disclaimer hier, houd er rekening mee dat de planner voor het uitvoeren van query's niet dom is, het kan meerdere niet-geclusterde indexen samen gebruiken om de juiste resultaten te produceren, dus de bovenstaande voorbeelden zijn misschien niet de beste die beschikbaar zijn, omdat het erg moeilijk voor te stellen is wanneer je nodig zou hebben 3 verschillende indexen die dezelfde kolom dekken, maar ik weet zeker dat je het idee begrijpt.)

De typen index, hun kolommen, opgenomen kolommen, sorteervolgorde, filters enz. zijn volledig afhankelijk van de situatie. U moet dekkingsindexen maken om aan verschillende soorten zoekopdrachten te voldoen, evenals aangepaste indexen die speciaal zijn gemaakt voor enkelvoudige, belangrijke zoekopdrachten. Elke index neemt ruimte in beslag op de HDD, dus het maken van nutteloze indexen is verspilling en vereist extra onderhoud wanneer het datamodel verandert, en het verspilt echter tijd aan defragmentatie en het bijwerken van statistieken... dus u wilt niet zomaar overal een index op plakken ofwel.

Experimenteer, leer en werk uit wat het beste werkt voor uw behoeften.



  1. tijdstempelwaarden invoegen in stappen van 3 minuten

  2. XMLAGG met RTRIM-probleem

  3. Hoe controleert Zend\Db in ZF2 transacties?

  4. T-SQL en de WHERE LIKE %Parameter%-clausule