Šta su indeksi u sql. SQL - Indeksi. Zašto se klasterirani i negrupisani indeksi nazivaju B-stablo u SQL Serveru?

Jedan od najvažnijih načina za postizanje Visoke performanse SQL Server je upotreba indeksa. Indeks ubrzava proces upita pružanjem brz pristup na redove podataka u tabeli, slično kao što vam indeks u knjizi pomaže da brzo pronađete informacije koje su vam potrebne. U ovom članku ću dati kratka recenzija indeksira u SQL Server i objasniti kako su organizirani u bazi podataka i kako pomažu da se ubrzaju upiti baze podataka.

Indeksi se kreiraju na tablicama i kolonama pogleda. Indeksi pružaju način za brzo pretraživanje podataka na osnovu vrijednosti u tim stupcima. Na primjer, ako kreirate indeks na primarnom ključu, a zatim tražite red podataka koristeći vrijednosti primarnog ključa, tada SQL Serverće prvo pronaći vrijednost indeksa, a zatim koristiti indeks da brzo pronađe cijeli red podataka. Bez indeksa, izvršiće se potpuno skeniranje svih redova u tabeli, što može imati značajan uticaj na performanse.
Možete kreirati indeks za većinu kolona u tabeli ili prikazu. Izuzetak su uglavnom kolone sa tipovima podataka za pohranjivanje velikih objekata ( LOB), kao što je slika, tekst ili varchar(max). Također možete kreirati indekse na stupcima dizajniranim za pohranjivanje podataka u formatu XML, ali su ovi indeksi strukturirani nešto drugačije od standardnih i njihovo razmatranje je izvan okvira ovog članka. Također, članak ne raspravlja columnstore indeksi. Umjesto toga, fokusiram se na one indekse koji se najčešće koriste u bazama podataka SQL Server.
Indeks se sastoji od skupa stranica, indeksnih čvorova, koji su organizovani u strukturu stabla - balansirano drvo. Ova struktura je hijerarhijske prirode i počinje s korijenskim čvorom na vrhu hijerarhije i listovima, listovima, na dnu, kao što je prikazano na slici:


Kada postavljate upit prema indeksiranoj koloni, mašina za upite počinje na vrhu korijenskog čvora i radi svoj put prema dolje kroz međučvorove, pri čemu svaki međusloj sadrži detaljnije informacije o podacima. Mehanizam upita nastavlja da se kreće kroz indeksne čvorove sve dok ne dostigne donji nivo sa listovima indeksa. Na primjer, ako tražite vrijednost 123 u indeksiranoj koloni, mašina za upite će prvo odrediti stranicu na prvom srednjem nivou na osnovnom nivou. U ovom slučaju, prva stranica ukazuje na vrijednost od 1 do 100, a druga od 101 do 200, tako da će mašina za upite pristupiti drugoj stranici ovog srednjeg nivoa. Zatim ćete vidjeti da biste trebali okrenuti treću stranicu sljedećeg srednjeg nivoa. Odavde će podsistem upita pročitati vrijednost samog indeksa na nižem nivou. Listovi indeksa mogu sadržavati ili same podatke tablice ili jednostavno pokazivač na redove s podacima u tablici, ovisno o tipu indeksa: klasterirani indeks ili neklasterirani indeks.

Grupirani indeks
Grupirani indeks pohranjuje stvarne redove podataka u listovima indeksa. Vraćajući se na prethodni primjer, to znači da će red podataka pridruženih ključnoj vrijednosti 123 biti pohranjen u samom indeksu. Važna karakteristika Grupirani indeks je da su sve vrijednosti sortirane određenim redoslijedom, bilo uzlaznim ili opadajućim. Stoga, tablica ili pogled može imati samo jedan klasterizirani indeks. Osim toga, treba napomenuti da se podaci u tablici pohranjuju u sortiranom obliku samo ako je na ovoj tablici kreiran klasterirani indeks.
Tabela koja nema grupirani indeks naziva se hrpa.
Neklasterirani indeks
Za razliku od grupiranog indeksa, listovi indeksa koji nisu grupirani sadrže samo te stupce ( ključ) kojim se ovaj indeks određuje, a sadrži i pokazivač na redove sa stvarnim podacima u tabeli. To znači da sistem podupita zahtijeva dodatnu operaciju za lociranje i dohvaćanje potrebnih podataka. Sadržaj pokazivača podataka ovisi o tome kako se podaci pohranjuju: klasterirana tablica ili hrpa. Ako pokazivač pokazuje na grupisanu tabelu, on pokazuje na klasterizovani indeks koji se može koristiti za pronalaženje stvarnih podataka. Ako se pokazivač odnosi na hrpu, onda pokazuje na određeni identifikator reda podataka. Neklasterirani indeksi se ne mogu sortirati kao klasterirani indeksi, ali možete kreirati više od jednog neklasteriziranog indeksa na tablici ili prikazu, do 999. To ne znači da biste trebali kreirati što je više moguće indeksa. Indeksi mogu poboljšati ili degradirati performanse sistema. Osim što možete kreirati više indeksa koji nisu grupirani, možete uključiti i dodatne stupce ( uključena kolona) u svoj indeks: listovi indeksa će pohraniti ne samo vrijednost samih indeksiranih stupaca, već i vrijednosti ovih neindeksiranih dodatnih stupaca. Ovaj pristup će vam omogućiti da zaobiđete neka ograničenja postavljena na indeks. Na primjer, možete uključiti stupac koji se ne može indeksirati ili zaobići ograničenje dužine indeksa (900 bajtova u većini slučajeva).

Vrste indeksa

Osim što je klasterirani ili neklasterni indeks, može se dalje konfigurirati kao kompozitni indeks, jedinstveni indeks ili indeks pokrivanja.
Kompozitni indeks
Takav indeks može sadržavati više od jedne kolone. Možete uključiti do 16 kolona u indeks, ali njihova ukupna dužina je ograničena na 900 bajtova. I klasterirani i neklasterirani indeksi mogu biti složeni.
Jedinstveni indeks
Ovaj indeks osigurava da je svaka vrijednost u indeksiranoj koloni jedinstvena. Ako je indeks kompozitni, tada se jedinstvenost primjenjuje na sve stupce u indeksu, ali ne i na svaki pojedinačni stupac. Na primjer, ako kreirate jedinstveni indeks na stupcima NAME I PREZIME, To puno ime mora biti jedinstven, ali su duplikati u imenu ili prezimenu mogući.
Jedinstveni indeks se automatski kreira kada definirate ograničenje stupca: primarni ključ ili ograničenje jedinstvene vrijednosti:
  • Primarni ključ
    Kada definirate ograničenje primarnog ključa na jednom ili više stupaca tada SQL Server automatski kreira jedinstveni klasterirani indeks ako klasterirani indeks nije prethodno kreiran (u ovom slučaju, jedinstveni ne-klasterirani indeks se kreira na primarnom ključu)
  • Jedinstvenost vrijednosti
    Kada definirate ograničenje na jedinstvenost vrijednosti onda SQL Server automatski kreira jedinstveni neklasterirani indeks. Možete odrediti da se kreira jedinstveni klasterirani indeks ako u tablici još nije kreiran klasterirani indeks
Indeks pokrivanja
Takav indeks omogućava specifičnom upitu da odmah dobije sve potrebne podatke iz listova indeksa bez dodatnog pristupa zapisima same tabele.

Dizajniranje indeksa

Koliko god indeksi bili korisni, moraju biti pažljivo dizajnirani. Budući da indeksi mogu zauzeti značajan prostor na disku, ne želite da kreirate više indeksa nego što je potrebno. Osim toga, indeksi se automatski ažuriraju kada se ažurira sam red podataka, što može dovesti do dodatnih troškova resursa i degradacije performansi. Prilikom dizajniranja indeksa, nekoliko razmatranja u vezi sa bazom podataka i upitima prema njoj mora se uzeti u obzir.
Baza podataka
Kao što je ranije navedeno, indeksi mogu poboljšati performanse sistema jer oni pružaju mašini za upite brz način za pronalaženje podataka. Međutim, također biste trebali uzeti u obzir koliko često namjeravate umetnuti, ažurirati ili izbrisati podatke. Kada promijenite podatke, indeksi se također moraju promijeniti da odražavaju odgovarajuće radnje na podacima, što može značajno smanjiti performanse sistema. Uzmite u obzir sljedeće smjernice kada planirate svoju strategiju indeksiranja:
  • Za tabele koje se često ažuriraju, koristite što manje indeksa.
  • Ako tabela sadrži veliku količinu podataka, ali su promjene male, onda koristite onoliko indeksa koliko je potrebno da poboljšate performanse vaših upita. Međutim, dobro razmislite prije korištenja indeksa na malim tablicama, jer... Moguće je da korištenje indeksnog pretraživanja može potrajati duže od jednostavnog skeniranja svih redova.
  • Za grupisane indekse, pokušajte da polja budu što kraća. Najbolji pristup je korištenje grupisanog indeksa na stupcima koji imaju jedinstvene vrijednosti i ne dozvoljavaju NULL. Zbog toga se primarni ključ često koristi kao klasterirani indeks.
  • Jedinstvenost vrijednosti u stupcu utiče na performanse indeksa. Općenito, što više duplikata imate u koloni, indeks je lošiji. S druge strane, što je više jedinstvenih vrijednosti, to je bolji učinak indeksa. Koristite jedinstveni indeks kad god je to moguće.
  • Za složeni indeks, uzmite u obzir redoslijed stupaca u indeksu. Kolone koje se koriste u izrazima GDJE(Na primjer, WHERE FirstName = "Charlie") mora biti prvi u indeksu. Sledeće kolone treba da budu navedene na osnovu jedinstvenosti njihovih vrednosti (prve su kolone sa najvećim brojem jedinstvenih vrednosti).
  • Također možete specificirati indeks za izračunate stupce ako ispunjavaju određene zahtjeve. Na primjer, izrazi koji se koriste za dobivanje vrijednosti stupca moraju biti deterministički (uvijek vraćaju isti rezultat za dati skup ulaznih parametara).
Upiti baze podataka
Još jedno razmatranje prilikom dizajniranja indeksa je koji se upiti pokreću prema bazi podataka. Kao što je ranije rečeno, morate uzeti u obzir koliko često se podaci mijenjaju. Osim toga, treba koristiti sljedeće principe:
  • Pokušajte umetnuti ili izmijeniti što više redova u jednom upitu, umjesto da to radite u nekoliko pojedinačnih upita.
  • Kreirajte negrupisani indeks na stupcima koji se često koriste kao pojmovi za pretraživanje u vašim upitima. GDJE i veze u PRIDRUŽITE SE.
  • Razmislite o indeksiranju stupaca koji se koriste u upitima za traženje reda za tačna podudaranja vrijednosti.

A sada, zapravo:

14 pitanja o indeksima u SQL Serveru koja vam je bilo neugodno postaviti

Zašto tabela ne može imati dva grupirana indeksa?

Želite kratak odgovor? Grupirani indeks je tabela. Kada kreirate grupirani indeks na tablici, mehanizam za pohranu sortira sve redove u tablici uzlaznim ili silaznim redoslijedom, prema definiciji indeksa. Grupirani indeks nije poseban entitet kao drugi indeksi, već mehanizam za sortiranje podataka u tabeli i omogućavanje brzog pristupa redovima podataka.
Zamislimo da imate tabelu koja sadrži istoriju prodajnih transakcija. Tabela prodaje uključuje informacije kao što su ID narudžbe, pozicija proizvoda u narudžbi, broj proizvoda, količina proizvoda, broj i datum narudžbe itd. Na stupcima kreirate grupirani indeks OrderID I LineID, sortirano uzlaznim redoslijedom kao što je prikazano u nastavku T-SQL kod:
KREIRAJTE JEDINSTVEN CLUSTERED INDEX ix_oriderid_lineid NA dbo.Sales(OrderID, LineID);
Kada pokrenete ovu skriptu, svi redovi u tabeli će biti fizički sortirani prvo po OrderID koloni, a zatim po LineID-u, ali sami podaci će ostati u jednom logičkom bloku, tabeli. Iz tog razloga ne možete kreirati dva klasterirana indeksa. Može postojati samo jedna tabela sa jednim podacima i ta tabela se može sortirati samo jednom određenim redosledom.

Ako klasterirana tabela pruža mnoge prednosti, zašto onda koristiti hrpu?

Upravu si. Grupirane tabele su sjajne i većina vaših upita će imati bolji učinak na tabelama koje imaju klasterizovani indeks. Ali u nekim slučajevima možda želite da ostavite stolove u njihovom prirodnom, netaknutom stanju, tj. u obliku hrpe i kreirajte samo indekse koji nisu grupirani da bi vaši upiti ostali aktivni.
Hrpa, kao što se sjećate, pohranjuje podatke nasumičnim redoslijedom. Tipično, podsistem za skladištenje dodaje podatke u tabelu redosledom kojim su umetnuti, ali podsistem skladištenja takođe voli da pomera redove radi efikasnijeg skladištenja. Kao rezultat toga, nemate priliku predvidjeti kojim će redoslijedom podaci biti pohranjeni.
Ako mehanizam za upite treba da pronađe podatke bez prednosti neklasteriranog indeksa, izvršit će potpuno skeniranje tablice kako bi pronašao redove koji su mu potrebni. Na vrlo malim tablicama to obično nije problem, ali kako hrpa raste u veličini, performanse brzo opadaju. Naravno, negrupisani indeks može pomoći korištenjem pokazivača na datoteku, stranicu i red gdje su pohranjeni potrebni podaci - obično je to mnogo više najbolja alternativa skeniranje stola. Čak i tako, teško je uporediti prednosti grupisanog indeksa kada se razmatra performanse upita.
Međutim, hrpa može pomoći u poboljšanju performansi u određenim situacijama. Razmotrite sto sa veliki iznos umetanja, ali sa rijetkim ažuriranjima ili brisanjem podataka. Na primjer, tablica koja pohranjuje dnevnik prvenstveno se koristi za umetanje vrijednosti dok se ne arhivira. Na hrpi nećete vidjeti stranice i fragmentaciju podataka kao što biste to vidjeli kod grupisanog indeksa jer se redovi jednostavno dodaju na kraj hrpe. Previše dijeljenja stranica može imati značajan utjecaj na performanse, i to ne na dobar način. Općenito, hrpa vam omogućava da ubacite podatke relativno bezbolno i nećete morati da se bavite troškovima skladištenja i održavanja kao što biste radili s klasteriranim indeksom.
Ali nedostatak ažuriranja i brisanja podataka ne treba smatrati jedinim razlogom. Način na koji su podaci uzorkovani je takođe važan faktor. Na primjer, ne biste trebali koristiti hrpu ako često postavljate upite za opsege podataka ili podatke koje tražite često treba sortirati ili grupirati.
Sve ovo znači da biste trebali razmisliti o korištenju hrpe samo kada radite s vrlo malim tablicama ili je sva vaša interakcija s tablicom ograničena na umetanje podataka, a vaši upiti su izuzetno jednostavni (i koristite ne-klasterirane indekse u svakom slučaju). U suprotnom, držite se dobro dizajniranog grupisanog indeksa, kao što je onaj definiran na jednostavnom rastućem ključnom polju, poput široko korištene kolone sa IDENTITET.

Kako mogu promijeniti zadani faktor popunjavanja indeksa?

Promjena zadanog faktora popunjavanja indeksa je jedna stvar. Razumevanje načina na koji radi podrazumevani odnos je druga stvar. Ali prvo se vratite nekoliko koraka unazad. Faktor popunjavanja indeksa određuje količinu prostora na stranici za pohranjivanje indeksa na donjem nivou (nivo lista) prije početka popunjavanja nova stranica. Na primjer, ako je koeficijent postavljen na 90, onda kada indeks raste, on će zauzeti 90% stranice, a zatim će se preći na sljedeću stranicu.
Prema zadanim postavkama, vrijednost faktora popunjavanja indeksa je in SQL Server je 0, što je isto kao i 100. Kao rezultat toga, svi novi indeksi automatski nasljeđuju ovu postavku osim ako posebno navedete vrijednost u svom kodu koja se razlikuje od standardne vrijednosti sistema ili promijenite zadano ponašanje. Možeš koristiti SQL Server Management Studio za podešavanje zadane vrijednosti ili pokretanje sistemske pohranjene procedure sp_configure. Na primjer, sljedeći set T-SQL naredba postavlja vrijednost koeficijenta na 90 (prvo se morate prebaciti na mod naprednih postavki):
EXEC sp_configure "prikaži napredne opcije", 1; GO RECONFIGURE; GO EXEC sp_configure "faktor popunjavanja", 90; GO RECONFIGURE; GO
Nakon promjene vrijednosti faktora popunjavanja indeksa, morate ponovo pokrenuti uslugu SQL Server. Sada možete provjeriti postavljenu vrijednost pokretanjem sp_configure bez navedenog drugog argumenta:
EXEC sp_configure "faktor popunjavanja" GO
Ova naredba bi trebala vratiti vrijednost od 90. Kao rezultat, svi novokreirani indeksi će koristiti ovu vrijednost. Ovo možete testirati kreiranjem indeksa i upitom za vrijednost faktora popunjavanja:
USE AdventureWorks2012; -- vaša baza podataka GO CREATE NENCLUSTERED INDEX ix_people_lastname NA Person.Person(Prezime); IDI SELECT fill_factor FROM sys.indexes GDJE object_id = object_id("Person.Person") AND name="ix_people_lastname";
IN u ovom primjeru kreirali smo neklasterirani indeks na tabeli Osoba u bazi podataka AdventureWorks2012. Nakon kreiranja indeksa, možemo dobiti vrijednost faktora popunjavanja iz sistemskih tablica sys.indexes. Upit bi trebao vratiti 90.
Međutim, zamislimo da smo izbrisali indeks i ponovo ga kreirali, ali sada smo naveli specifičnu vrijednost faktora popunjavanja:
CREATE NENCLUSTERED INDEX ix_people_lastname ON Person.Person(Prezime) WITH (filfactor=80); IDI SELECT fill_factor FROM sys.indexes GDJE object_id = object_id("Person.Person") AND name="ix_people_lastname";
Ovaj put smo dodali uputstva WITH i opciju fillfactor za našu operaciju kreiranja indeksa CREATE INDEX i specificirao vrijednost 80. Operator SELECT sada vraća odgovarajuću vrijednost.
Do sada je sve bilo prilično jednostavno. Ono u čemu se zaista možete izgorjeti u cijelom ovom procesu je kada kreirate indeks koji koristi zadanu vrijednost koeficijenta, pod pretpostavkom da znate tu vrijednost. Na primjer, neko petlja sa postavkama servera i toliko je tvrdoglav da je postavio faktor popunjavanja indeksa na 20. U međuvremenu, nastavljate da kreirate indekse, pod pretpostavkom da je zadana vrijednost 0. Nažalost, nemate načina da saznate popunjenost faktor sve dok ne kreirate indeks, a zatim provjerite vrijednost kao što smo radili u našim primjerima. U suprotnom, moraćete da sačekate trenutak kada performanse upita toliko opadnu da počnete da sumnjate u nešto.
Još jedan problem kojeg biste trebali biti svjesni je ponovna izgradnja indeksa. Kao i kod kreiranja indeksa, možete odrediti vrijednost faktora popunjavanja indeksa kada ga ponovo izgradite. Međutim, za razliku od naredbe create index, rebuild ne koristi zadane postavke servera, uprkos tome kako to može izgledati. Čak i više, ako ne navedete posebno vrijednost faktora popunjavanja indeksa, onda SQL Server koristiće vrijednost koeficijenta s kojim je ovaj indeks postojao prije njegovog restrukturiranja. Na primjer, sljedeća operacija ALTER INDEX ponovo gradi indeks koji smo upravo kreirali:
ALTER INDEX ix_people_lastname ON Person.Person REBUILD; IDI SELECT fill_factor FROM sys.indexes GDJE object_id = object_id("Person.Person") AND name="ix_people_lastname";
Kada provjerimo vrijednost faktora popunjavanja, dobićemo vrijednost od 80, jer je to ono što smo naveli kada smo zadnji put kreirali indeks. Zadana vrijednost se zanemaruje.
Kao što vidite, promjena vrijednosti faktora popunjavanja indeksa nije tako teška. Mnogo je teže znati trenutnu vrijednost i razumjeti kada se ona primjenjuje. Ako uvijek posebno specificirate koeficijent pri kreiranju i ponovnoj izgradnji indeksa, tada uvijek znate konkretan rezultat. Osim ako ne morate da brinete o tome da neko drugi ponovo ne zezne podešavanja servera, uzrokujući da se svi indeksi ponovo izgrade sa smešno niskim faktorom popunjavanja indeksa.

Da li je moguće kreirati grupirani indeks na koloni koja sadrži duplikate?

Da i ne. Da, možete kreirati grupirani indeks na ključnom stupcu koji sadrži duple vrijednosti. Ne, vrijednost stupca ključa ne može ostati u nejedinstvenom stanju. Dopusti mi da objasnim. Ako kreirate nejedinstveni grupirani indeks na stupcu, mehanizam za pohranu dodaje unifikator dupliranoj vrijednosti kako bi osigurao jedinstvenost i stoga mogao identificirati svaki red u grupisanoj tablici.
Na primjer, možete odlučiti da kreirate grupirani indeks na stupcu koji sadrži podatke korisnika Prezime zadržavanje prezimena. Kolona sadrži vrijednosti Franklin, Hancock, Washington i Smith. Zatim ponovo ubacujete vrijednosti Adams, Hancock, Smith i Smith. Ali vrijednost ključnog stupca mora biti jedinstvena, tako da će mehanizam za pohranu promijeniti vrijednost duplikata tako da izgledaju otprilike ovako: Adams, Franklin, Hancock, Hancock1234, Washington, Smith, Smith4567 i Smith5678.
Na prvi pogled, ovaj pristup izgleda u redu, ali cjelobrojna vrijednost povećava veličinu ključa, što može postati problem ako postoji veliki broj duplikata, a te vrijednosti će postati osnova neklasteriranog indeksa ili stranog ključna referenca. Iz ovih razloga, uvijek biste trebali pokušati kreirati jedinstvene klasterizirane indekse kad god je to moguće. Ako to nije moguće, onda najmanje pokušajte koristiti stupce s vrlo visokim sadržajem jedinstvenih vrijednosti.

Kako se tabela pohranjuje ako nije kreiran grupirani indeks?

SQL Server podržava dvije vrste tablica: klasterirane tablice koje imaju grupirani indeks i hrpe tablica ili samo hrpe. Za razliku od klasteriranih tabela, podaci na hrpi nisu sortirani ni na koji način. U suštini, ovo je gomila (gomila) podataka. Ako takvoj tabeli dodate red, mehanizam za skladištenje će ga jednostavno dodati na kraj stranice. Kada se stranica popuni podacima, bit će dodana na novu stranicu. U većini slučajeva, htjet ćete kreirati grupirani indeks na tablici kako biste iskoristili prednosti sortiranja i bržih upita (probajte zamisliti pronalaženje telefonski broj u adresaru koji nije sortiran ni po jednom principu). Međutim, ako odlučite da ne kreirate klasterizovani indeks, i dalje možete kreirati neklasterizovani indeks na hrpi. U ovom slučaju, svaki red indeksa će imati pokazivač na red hrpe. Indeks uključuje ID datoteke, broj stranice i broj reda podataka.

Kakav je odnos između ograničenja jedinstvenosti vrijednosti i primarnog ključa s indeksima tablice?

Primarni ključ i jedinstveno ograničenje osiguravaju da su vrijednosti u stupcu jedinstvene. Možete kreirati samo jedan primarni ključ za tabelu i ne može sadržavati vrijednosti NULL. Možete kreirati nekoliko ograničenja za jedinstvenost vrijednosti za tablicu, a svako od njih može imati jedan zapis sa NULL.
Kada kreirate primarni ključ, mehanizam za pohranu također kreira jedinstveni klasterirani indeks ako klasterirani indeks već nije kreiran. Međutim, možete nadjačati zadano ponašanje i kreirat će se neklasterirani indeks. Ako klasterirani indeks postoji kada kreirate primarni ključ, kreirat će se jedinstveni neklasterirani indeks.
Kada kreirate jedinstveno ograničenje, mehanizam za skladištenje kreira jedinstveni, neklasterizovani indeks. Međutim, možete specificirati kreiranje jedinstvenog klasteriranog indeksa ako nije prethodno kreiran.
Općenito, ograničenje jedinstvene vrijednosti i jedinstveni indeks su ista stvar.

Zašto se grupirani i neklasterizovani indeksi u SQL Serveru nazivaju B-stablo?

Osnovni indeksi u SQL Serveru, grupisani ili neklasterisani, distribuiraju se preko skupova stranica koje se nazivaju indeksni čvorovi. Ove stranice su organizirane u specifičnoj hijerarhiji sa strukturom stabla koja se naziva uravnoteženo stablo. Na gornjem nivou nalazi se korijenski čvor, na dnu su čvorovi lista, sa međučvorovima između gornjeg i donjeg nivoa, kao što je prikazano na slici:


Korijenski čvor pruža glavnu ulaznu tačku za upite koji pokušavaju da dohvate podatke kroz indeks. Počevši od ovog čvora, podsistem upita pokreće tranziciju hijerarhijska struktura sve do odgovarajućeg lisnog čvora koji sadrži podatke.
Na primjer, zamislite da je primljen zahtjev za odabir redova koji sadrže ključnu vrijednost 82. Podsistem upita počinje raditi od korijenskog čvora, koji se odnosi na odgovarajući međučvor, u našem slučaju 1-100. Od srednjeg čvora 1-100 dolazi do prijelaza na čvor 51-100, a odatle u konačni čvor 76-100. Ako je ovo klasterizirani indeks, tada list čvora sadrži podatke reda pridruženog ključu jednak 82. Ako je ovo neklasterizirani indeks, onda list indeksa sadrži pokazivač na klasteriziranu tablicu ili određeni red u gomila.

Kako indeks može čak poboljšati performanse upita ako morate proći kroz sve ove čvorove indeksa?

Prvo, indeksi ne poboljšavaju uvijek performanse. Previše pogrešno kreiranih indeksa pretvara sistem u blato i degradira performanse upita. Tačnije je reći da ako se indeksi pažljivo primjenjuju, oni mogu pružiti značajne dobitke u performansama.
Zamislite veliku knjigu posvećenu podešavanju performansi SQL Server(papirna verzija, ne elektronska verzija). Zamislite da želite pronaći informacije o konfiguriranju Resource Governora. Možete prstom prevlačiti stranicu po stranicu kroz cijelu knjigu ili otvoriti sadržaj i saznati tačan broj stranice sa informacijama koje tražite (pod uslovom da je knjiga ispravno indeksirana i sadržaj ima ispravne indekse). Ovo će vam svakako uštedjeti značajno vrijeme, iako prvo morate pristupiti potpuno drugoj strukturi (indeksu) da biste dobili informacije koje su vam potrebne iz primarne strukture (knjige).
Kao indeks knjige, indeks u SQL Server omogućava vam da pokrenete precizne upite o podacima koji su vam potrebni umjesto da potpuno skenirate sve podatke sadržane u tabeli. Za male tabele, potpuno skeniranje obično nije problem, ali velike tabele zauzimaju mnogo stranica podataka, što može rezultirati značajnim vremenom izvršenja upita osim ako ne postoji indeks koji bi omogućio mašini za upite da odmah dobije tačnu lokaciju podataka. Zamislite da se izgubite na raskrsnici na više nivoa ispred velike metropole bez mape i shvatit ćete.

Ako su indeksi tako sjajni, zašto jednostavno ne napravite po jedan na svakoj koloni?

Nijedno dobro djelo ne smije ostati nekažnjeno. Barem je to slučaj sa indeksima. Naravno, indeksi rade odlično sve dok pokrećete upite za dohvaćanje operatora SELECT, ali čim počnu česti pozivi operaterima INSERT, UPDATE I IZBRIŠI, tako da se pejzaž vrlo brzo mijenja.
Kada pokrenete zahtjev za podacima od strane operatera SELECT, mehanizam upita pronalazi indeks, kreće se kroz njegovu strukturu stabla i otkriva podatke koje traži. Šta može biti jednostavnije? Ali stvari se mijenjaju ako pokrenete izjavu o promjeni kao što je UPDATE. Da, za prvi dio izjave, mehanizam upita ponovo može koristiti indeks da locira red koji se mijenja - to je dobra vijest. A ako postoji jednostavna promjena podataka u redu koja ne utječe na promjene u ključnim stupcima, tada će proces promjene biti potpuno bezbolan. Ali šta ako promjena uzrokuje podjelu stranica koje sadrže podatke ili se promijeni vrijednost ključnog stupca zbog čega se premješta na drugi indeksni čvor - to će rezultirati da će indeksu možda biti potrebna reorganizacija koja će utjecati na sve povezane indekse i operacije , što dovodi do široko rasprostranjenog pada produktivnosti.
Slični procesi se dešavaju prilikom pozivanja operatera IZBRIŠI. Indeks može pomoći u lociranju podataka koji se brišu, ali brisanje samih podataka može dovesti do ponovnog premještanja stranica. Što se tiče operatera INSERT, glavni neprijatelj svih indeksa: počnete da dodajete veliku količinu podataka, što dovodi do promjena u indeksima i njihove reorganizacije i svi trpe.
Stoga uzmite u obzir tipove upita vašoj bazi podataka kada razmišljate o tome koju vrstu indeksa i koliko ih kreirati. Više ne znači bolje. Prije dodavanja novog indeksa u tablicu, uzmite u obzir troškove ne samo osnovnih upita, već i količinu potrošenog prostora na disku, troškove održavanja funkcionalnosti i indeksa, što može dovesti do domino efekta na druge operacije. Vaša strategija dizajna indeksa jedan je od najvažnijih aspekata vaše implementacije i trebala bi uključiti mnoga razmatranja, od veličine indeksa, broja jedinstvenih vrijednosti, do vrste upita koje će indeks podržavati.

Da li je potrebno kreirati grupirani indeks na koloni s primarnim ključem?

Možete kreirati grupirani indeks na bilo kojoj koloni koja ispunjava tražene uslove. Istina je da su klasterirani indeks i ograničenje primarnog ključa napravljeni jedno za drugo i da se podudaraju na nebu, pa shvatite činjenicu da kada kreirate primarni ključ, onda će klasterirani indeks biti automatski kreiran ako nije bio kreiran ranije. Međutim, možete odlučiti da bi klasterizirani indeks imao bolji učinak negdje drugdje, a često će vaša odluka biti opravdana.
Glavna svrha grupisanog indeksa je da sortira sve redove u vašoj tabeli na osnovu ključne kolone koja je navedena prilikom definisanja indeksa. Ovo obezbeđuje brza pretraga I lak pristup na podatke tabele.
Primarni ključ tabele može biti dobar izbor jer jedinstveno identifikuje svaki red u tabelama bez potrebe za dodavanjem dodatnih podataka. U nekim slučajevima najbolji izbor Postojaće surogat primarni ključ koji nije samo jedinstven, već je i male veličine, i čije vrijednosti se uzastopno povećavaju, što čini ne-klasterirane indekse zasnovane na ovoj vrijednosti efikasnijim. Optimizator upita također voli ovu kombinaciju klasteriranog indeksa i primarnog ključa jer je spajanje tabela brže od spajanja na drugi način koji ne koristi primarni ključ i njegov pridruženi klasterirani indeks. Kao što sam rekao, to je šibica napravljena na nebu.
Na kraju, međutim, vrijedno je napomenuti da prilikom kreiranja grupisanog indeksa postoji nekoliko aspekata koje treba uzeti u obzir: koliko će neklasteriranih indeksa biti zasnovano na njemu, koliko često će se mijenjati vrijednost stupca ključnog indeksa i koliko velika. Kada se vrijednosti u stupcima grupiranog indeksa promijene ili indeks ne radi kako se očekivalo, to može utjecati na sve ostale indekse u tablici. Grupirani indeks bi trebao biti zasnovan na najtrajnijoj koloni čije se vrijednosti povećavaju određenim redoslijedom, ali se ne mijenjaju na slučajan način. Indeks mora podržavati upite prema podacima tablice kojima se najčešće pristupa, tako da upiti u potpunosti iskorištavaju činjenicu da su podaci sortirani i dostupni na korijenskim čvorovima, listovima indeksa. Ako primarni ključ odgovara ovom scenariju, onda ga upotrijebite. Ako ne, odaberite drugi skup kolona.

Šta ako indeksirate pogled, da li je to još uvijek pogled?

Prezentacija je virtuelni sto, koji generiše podatke iz jedne ili više tabela. U suštini, to je imenovani upit koji dohvaća podatke iz osnovnih tabela kada postavljate upit za taj pogled. Možete poboljšati performanse upita kreiranjem grupisanog indeksa i neklasteriziranih indeksa na ovom prikazu, slično kao što kreirate indekse na tablici, ali glavno upozorenje je da prvo kreirate klasterirani indeks, a zatim možete kreirati neklasterirani indeks.
Kada se kreira indeksirani pogled (materijalizirani pogled), onda sama definicija pogleda ostaje zaseban entitet. Ovo je, na kraju krajeva, samo tvrdo kodirani operator SELECT, pohranjen u bazi podataka. Ali indeks je sasvim druga priča. Kada kreirate grupirani ili neklasterizovani indeks na dobavljaču, podaci se fizički spremaju na disk, baš kao i običan indeks. Osim toga, kada se podaci promijene u osnovnim tabelama, indeks pogleda se automatski mijenja (to znači da biste mogli izbjeći indeksiranje pogleda na tabelama koje se često mijenjaju). U svakom slučaju, pogled ostaje pogled - pogled na tabele, ali precizno izveden ovog trenutka, sa indeksima koji mu odgovaraju.
Prije nego što možete kreirati indeks na prikazu, on mora zadovoljiti nekoliko ograničenja. Na primjer, pogled može referencirati samo osnovne tablice, ali ne i druge poglede, a te tablice moraju biti u istoj bazi podataka. Zapravo postoje mnoga druga ograničenja, pa svakako provjerite dokumentaciju SQL Server za sve prljave detalje.

Zašto koristiti indeks pokrivanja umjesto kompozitnog indeksa?

Prvo, hajde da se uverimo da razumemo razliku između to dvoje. Složeni indeks je jednostavno običan indeks koji sadrži više od jedne kolone. Više ključnih kolona može se koristiti kako bi se osiguralo da je svaki od njih jedinstven redovi tabele, također je moguće da se primarni ključ sastoji od nekoliko kolona kako bi se osigurala njegova jedinstvenost ili pokušavate optimizirati izvršavanje često pozivanih upita na nekoliko kolona. Općenito, međutim, što više ključnih kolona indeks sadrži, to će indeks biti manje efikasan, što znači da bi kompozitne indekse trebalo razumno koristiti.
Kao što je rečeno, upit može imati velike koristi ako se svi potrebni podaci odmah nalaze na listovima indeksa, baš kao i sam indeks. Ovo nije problem za klasterizovani indeks jer svi podaci su već tamo (zbog čega je toliko važno da pažljivo razmislite kada kreirate klasterizovani indeks). Ali negrupisani indeks na listovima sadrži samo ključne stupce. Za pristup svim ostalim podacima, optimizator upita zahtijeva dodatne korake, koji mogu dodati značajne troškove izvršavanju vaših upita.
Tu u pomoć dolazi indeks pokrivanja. Kada definirate neklasterirani indeks, možete specificirati dodatne stupce svojim ključnim stupcima. Na primjer, recimo da vaša aplikacija često postavlja upite o podacima stupaca OrderID I OrderDate u tabeli Prodaja:
SELECT OrderID, OrderDate FROM Sales WHERE ID naloga = 12345;
Možete kreirati složeni negrupisani indeks na oba stupca, ali stupac OrderDate će samo dodati dodatne troškove održavanja indeksa bez da služi kao posebno korisna ključna kolona. Najbolja odluka bilo bi kreiranje indeksa pokrivanja na ključnoj koloni OrderID i dodatno uključena kolona OrderDate:
CREATE NENCLUSTERED INDEX ix_orderid NA dbo.Sales(OrderID) INCLUDE (OrderDate);
Time se izbjegavaju nedostaci indeksiranja suvišnih kolona dok se i dalje održavaju prednosti pohranjivanja podataka u listovima prilikom pokretanja upita. Uključena kolona nije dio ključa, ali podaci se pohranjuju na lisni čvor, indeksni list. Ovo može poboljšati performanse upita bez ikakvih dodatnih troškova. Osim toga, stupci uključeni u indeks pokrivanja podliježu manjem ograničenju od ključnih stupaca indeksa.

Da li je važan broj duplikata u ključnoj koloni?

Kada kreirate indeks, morate pokušati smanjiti broj duplikata u ključnim stupcima. Ili preciznije: pokušajte da učestalost ponavljanja bude što niža.
Ako radite sa složenim indeksom, tada se dupliranje primjenjuje na sve ključne stupce u cjelini. Jedna kolona može sadržavati mnogo dupliciranih vrijednosti, ali bi trebalo biti minimalno ponavljanje među svim stupcima indeksa. Na primjer, kreirate složeni neklasterirani indeks na stupcima Ime I Prezime, možete imati mnogo John Doe vrijednosti i mnogo vrijednosti Doe, ali želite imati što manje vrijednosti John Doea, ili po mogućnosti samo jednu John Doe vrijednost.
Omjer jedinstvenosti vrijednosti ključne kolone naziva se selektivnost indeksa. Što je više jedinstvenih vrijednosti, veća je selektivnost: jedinstveni indeks ima najveću moguću selektivnost. Mehanizam upita zaista voli kolone sa visokim vrijednostima selektivnosti, posebno ako su te kolone uključene u klauzule WHERE vaših najčešće izvršavanih upita. Što je indeks selektivniji, to brže mašina za upite može smanjiti veličinu rezultirajućeg skupa podataka. Loša strana je, naravno, to što će stupci sa relativno malo jedinstvenih vrijednosti rijetko biti dobri kandidati za indeksiranje.

Da li je moguće kreirati negrupisani indeks samo na određenom podskupu podataka ključne kolone?

Prema zadanim postavkama, neklasterirani indeks sadrži jedan red za svaki red u tablici. Naravno, isto možete reći i o grupisanom indeksu, pod pretpostavkom da je takav indeks tabela. Ali kada je u pitanju indeks koji nije grupiran, odnos jedan-na-jedan je važan koncept jer, počevši od verzije SQL Server 2008, imate mogućnost kreiranja indeksa koji se može filtrirati i koji ograničava redove uključene u njega. Filtrirani indeks može poboljšati performanse upita jer... manja je po veličini i sadrži filtriranu, precizniju statistiku od svih tabelarnih - to dovodi do kreiranja poboljšanih planova izvršenja. Filtrirani indeks također zahtijeva manje prostora za skladištenje i niže troškove održavanja. Indeks se ažurira samo kada se promijene podaci koji odgovaraju filteru.
Osim toga, indeks koji se može filtrirati je lako kreirati. U operateru CREATE INDEX samo treba naznačiti GDJE stanje filtera. Na primjer, možete filtrirati sve redove koji sadrže NULL iz indeksa, kao što je prikazano u kodu:
CREATE NENCLUSTERED INDEX ix_trackingnumber NA Sales.SalesOrderDetail(CarrierTrackingNumber) GDJE CarrierTrackingNumber NIJE NULL;
U stvari, možemo filtrirati sve podatke koji nisu važni u kritičnim upitima. Ali budite oprezni, jer... SQL Server nameće nekoliko ograničenja na indekse koji se mogu filtrirati, kao što je nemogućnost kreiranja indeksa koji se može filtrirati na prikazu, pa pažljivo pročitajte dokumentaciju.
Takođe može biti da možete postići slične rezultate kreiranjem indeksiranog prikaza. Međutim, filtrirani indeks ima nekoliko prednosti, kao što je mogućnost smanjenja troškova održavanja i poboljšanja kvalitete vaših planova izvršenja. Filtrirani indeksi se također mogu ponovo izgraditi na mreži. Pokušajte ovo sa indeksiranim prikazom.

I opet malo od prevodioca

Svrha izgleda ovog prevoda na stranicama Habrahabra trebalo je da vas ispriča ili podsjeti na blog SimpleTalk RedGate.
Objavljuje mnogo zabavnih i zanimljivih postova.
Nisam povezan sa proizvodima kompanije RedGate, niti njihovom prodajom.

Kao što sam obećao, knjige za one koji žele znati više
Preporučujem tri vrlo dobre knjige od sebe (linkovi vode do kindle verzije u prodavnici Amazon):

U principu, možete otvoriti jednostavne indekse Dodaj oznake
Microsoft SQL Server 2012 T-SQL osnove (referenca za programere)
Autor Itzik Ben-Gan
Datum objave: 15. jul 2012
Autor, majstor svog zanata, daje osnovno znanje o radu sa bazama podataka.
Ako ste sve zaboravili ili nikad niste znali, svakako je vrijedno pročitati.

ROWID indeksi su objekti baze podataka koji pružaju prikaz svih vrijednosti u stupcu tablice, kao i ROWID-ove svih redova u tablici koji sadrže vrijednosti stupca.

ROWID je pseudo-stupac koji je jedinstveni identifikator za red u tabeli i zapravo opisuje tačnu fizičku lokaciju tog određenog reda. Na osnovu ovih informacija Oracle može naknadno pronaći podatke povezane s redom tablice. Svaki put kada se red pomiče, izvozi, uvozi ili bilo koja druga operacija koja mijenja njegovu lokaciju, ROWID linija jer zauzima drugačiju fizičku poziciju. Za skladištenje podataka ROWID Potrebno je 80 bita (10 bajtova). Identifikatori ROWID sastoji se od četiri komponente: broja objekta (32 bita), relativnog broja datoteke (10 bita), broja bloka (22 bita) i broja reda (16 bita). Ovi identifikatori se prikazuju kao sekvence od 18 znakova koje ukazuju na lokaciju podataka u bazi podataka, pri čemu je svaki znak predstavljen u formatu base-64, koji se sastoji od znakovi A-Z, a-z, 0-9, + i /. Prvih šest znakova su broj objekta podataka, sljedeća tri su relativni broj datoteke, sljedećih šest su broj bloka, a posljednja tri su broj reda.

primjer:

ODABIR fam, ROWID OD studenta;

FAM ROWID

——————————————

IVANOV AAAA3kAAGAAAAGsAAA

PETROV AAAA3kAAGAAAAGsAAB

U bazi podataka Oracle indeksi se koriste u različite svrhe: da osiguraju jedinstvenost vrijednosti u bazi podataka, da poboljšaju performanse pretraživanja zapisa u tabeli, itd. Performanse se poboljšavaju uključivanjem reference na indeksirani stupac ili stupce u kriterije pretraživanja za podatke u tabeli. IN Oracle indeksi se mogu kreirati na bilo kojoj koloni tabele osim DUGA kolona. Indeksi razlikuju aplikacije koje nisu osjetljive na brzinu i aplikacije visokih performansi, posebno kada se radi s velikim tablicama. Međutim, prije nego što se odlučite za kreiranje indeksa, morate odmjeriti prednosti i nedostatke u pogledu performansi sistema. Performanse se neće poboljšati ako jednostavno unesete indeks i zaboravite na njega.

Iako najveće poboljšanje performansi dolazi od kreiranja indeksa na stupcu gdje su sve vrijednosti jedinstvene, možete dobiti slične rezultate za stupce koji sadrže duple ili NULL vrijednosti. Nije neophodno da vrijednosti stupca budu jedinstvene za kreiranje indeksa. Evo nekoliko preporuka koje će vam pomoći da postignete željeno povećanje performansi kada koristite standardni indeks, a takođe ćemo razmotriti probleme u vezi sa ravnotežom između performansi i potrošnje prostora na disku prilikom kreiranja indeksa.

Korištenje indeksa za traženje informacija u tablicama može pružiti značajna poboljšanja performansi u odnosu na skeniranje tablica čije kolone nisu indeksirane. Međutim, odabir pravog indeksa nije nimalo lak. Naravno, kolona čije su sve vrijednosti jedinstvene je poželjna za indeksiranje pomoću indeksa B-stabla, ali kolona koja ne ispunjava ove zahtjeve je dobar kandidat sve dok oko 10% njegovih redova sadrži identične vrijednosti i ne više. Stupci “Switch” ili “flag”, na primjer oni koji pohranjuju informacije o spolu osobe, nisu prikladni za indekse B-stabla. Kolone koje se koriste za pohranjivanje malog broja “pouzdanih vrijednosti”, kao i one koje pohranjuju određene vrijednosti, također nisu prikladne, onda znaci, na primjer, “pouzdanost” ili “nepouzdanost”, “aktivnost” ili “neaktivnost”, “da” ili “ne” itd., itd. Konačno, indeksi sa obrnutim ključevima su koristi se, po pravilu, tamo gde je instaliran i radi Oracle Paralelni server i potrebno je da povećate nivo paralelizma u bazi podataka do maksimuma.

Za početak, predlažem da shvatite o čemu se radi indeks pokrivanja, dat ću izvod iz članka na Habréu:

Zašto koristiti indeks pokrivanja umjesto kompozitnog indeksa?
Prvo, hajde da se uverimo da razumemo razliku između to dvoje.
Kompozitni indeks to je samo običan indeks koji uključuje više od jedne kolone. Više kolona ključeva može se koristiti da bi se osiguralo da je svaki red u tabeli jedinstven, ili možete imati više kolona kako biste osigurali da je primarni ključ jedinstven, ili možda pokušavate optimizirati izvršavanje često pozivanih upita na više kolona. Općenito, međutim, što više ključnih kolona indeks sadrži, to će indeks biti manje efikasan, što znači da bi kompozitne indekse trebalo razumno koristiti.

Kao što je rečeno, upit može imati velike koristi ako se svi potrebni podaci odmah nalaze na listovima indeksa, baš kao i sam indeks. Ovo nije problem za klasterizovani indeks jer svi podaci su već tamo (zbog čega je toliko važno da pažljivo razmislite kada kreirate klasterizovani indeks). Ali negrupisani indeks na listovima sadrži samo ključne stupce. Za pristup svim ostalim podacima, optimizator upita zahtijeva dodatne korake, koji mogu dodati značajne troškove izvršavanju vaših upita.

Eto gde indeks pokrivanjažuri u pomoć. Kada definirate neklasterirani indeks, možete specificirati dodatne stupce svojim ključnim stupcima.

Dakle, indeks pokrivanja ne bi trebao sadržavati sve stupce upita za odabir u strukturi stabla indeksa, već samo one koji će se koristiti za filtriranje ili grupiranje podataka u upitu, preostale kolone iz odjeljka SELECT treba staviti u INCLUDE odjeljak indeksa.

Možda će vam biti od pomoći odgovor iz drugog pitanja.

Gornji primjer koristi složeni indeks s 3 polja umjesto indeksa pokrivanja, kod za kreiranje indeksa pokrivanja bi izgledao ovako:

KREIRAJTE NEKLASTERIRAN INDEKS NA . ( ASC) UKLJUČUJE (, ) SA (PAD_INDEX = ISKLJUČENO, STATISTICS_NORECOMPUTE = ISKLJUČENO, SORT_IN_TEMPDB = ISKLJUČENO, IGNORE_DUP_KEY = ISKLJUČENO, DROP_EXISTING = ISKLJUČENO, ONLINE = ISKLJUČENO, ALLOW_ROW_LOCALLKS = UKLJUČENO, ALLOW_ROW_LOCALLKS_ON)

Da odgovorite na vaše pitanje:

za indeks pokrivanja, redoslijed stupaca u odjeljku INCLUE nebitno, ali redoslijed kolona je važan za kompozitni indeks, jer Podaci kolone se postavljaju u stablo indeksa redosledom kojim su kolone navedene, a optimizator upita neće moći da koristi indeks sa 2 kolone da traži vrednosti samo 2 kolone. Možete vidjeti jasan primjer kako će struktura indeksa 2 kolone (EMPLOYEE_ID, SUBSIDIARY_ID) izgledati na slici.

1) Koncept indeksa
Indeks je alat koji omogućava brz pristup redovima tabele na osnovu vrednosti jedne ili više kolona.

Postoji mnogo raznolikosti u ovom operateru jer nije standardiziran, jer standardi ne rješavaju probleme performansi.

2) Kreiranje indeksa
CREATE INDEX
UKLJUČENO()

3) Promjena i brisanje indeksa
Za kontrolu aktivnosti indeksa koristi se operator:
ALTER INDEX
Da biste uklonili indeks, koristite operator:
DROP INDEX

a) Pravila odabira tabele
1. Preporučljivo je indeksirati tabele u kojima nije odabrano više od 5% redova.
2. Tablice koje nemaju duplikate u klauzuli WHERE izraza SELECT trebaju biti indeksirane.
3. Nije praktično indeksirati često ažurirane tabele.
4. Neprikladno je indeksirati tabele koje ne zauzimaju više od 2 stranice (za Oracle je to manje od 300 redova), jer njegovo potpuno skeniranje ne traje duže.

b) Pravila odabira kolona
1. Primarni i strani ključevi – često se koriste za spajanje tabela, dohvaćanje podataka i pretraživanje. To su uvijek jedinstveni indeksi s maksimalnom korisnošću
2. Kada koristite opcije referentnog integriteta, uvijek vam je potreban indeks na FK-u.
3. Kolone po kojima se podaci često sortiraju i/ili grupišu.
4. Kolone koje se često pretražuju u klauzuli WHERE izraza SELECT.
5. Ne biste trebali kreirati indekse na dugim deskriptivnim stupcima.

c) Principi za kreiranje kompozitnih indeksa
1. Kompozitni indeksi su dobri ako pojedinačni stupci imaju malo jedinstvenih vrijednosti, ali složeni indeks pruža više jedinstvenosti.
2. Ako sve vrijednosti odabrane naredbom SELECT pripadaju kompozitnom indeksu, tada se vrijednosti biraju iz indeksa.
3. Složeni indeks treba kreirati ako klauzula WHERE koristi dvije ili više vrijednosti u kombinaciji sa operatorom AND.

d) Ne preporučuje se kreiranje
Ne preporučuje se kreiranje indeksa na stupcima, uključujući i one složene, koji:
1. Rijetko se koristi za pretraživanje, spajanje i sortiranje rezultata upita.
2. Sadrže vrijednosti koje se često mijenjaju, što zahtijeva česta ažuriranja index usporava performanse baze podataka.
3. Sadrži mali broj jedinstvenih vrijednosti (manje od 10% m/ž) ili preovlađujući broj linija sa jednom ili dvije vrijednosti (grad prebivališta dobavljača je Moskva).
4. Na njih se primjenjuju funkcije ili izraz u klauzuli WHERE, a indeks ne radi.

e) Ne smijemo zaboraviti
Treba težiti smanjenju broja indeksa, jer veliki broj njih smanjuje brzinu ažuriranja podataka. Stoga, MS SQL Server preporučuje kreiranje ne više od 16 indeksa po tabeli.
Obično se indeksi kreiraju za potrebe upita i za održavanje referentnog integriteta.
Ako se indeks ne koristi za upite, onda ga treba izbrisati i referentni integritet treba osigurati pomoću okidača.