OK, long time no see.. :))
Svi znamo da mozemo kreirati clustered indeks (CI) na (skoro) bilo kojem subsetu kolona iz tablice. Također, svi znamo da možemo kreirati nonclustered indekse (NCI) na (skoro) bilo kojem subsetu kolona iz tablice, manje-više neograničen broj njih.
Kod upita koje radimo na tablicu, kada access path prema podacima koji izabere SQL Server optimizer uključuje NCI, i ako taj NCI nije "covering" za taj upit, SQL Server mora pročitati ostale kolone koje mu trebaju tako da pristupi clustered indeksu*, ako ga imamo. Naravno, u slucaju da nemamo CI na tabli, prica se mijenja, i ostatku podataka se pristupa preko row identifikatora (RID). No, zadržimo se na ovom slučaju kad radimo seek na NCI na tabli s CI.
Svaki red u NCI, pored vrijednosni kolona koje čine indeks, sadrži i vrijednost CI, pomoću kojeg onda SQL Server pronalazi potreban red u CI, tj samoj tabli (jer CI nije nista drugo nego tabla, s indeksnom strukturom iznad sebe). Da bi se to moglo ostvariti, tj da bi SQL Server mogao locirati baš taj određeni red u tabli/CI, očito je da vrijednost CI mora biti unique za tablu. S druge strane, CI se može bez problema kreirati i nad non-unique kolonom, dakle može sadržavati iste vrijednosti indeksnih kolona za različite redove. Kako je onda moguće pronaći odgovarajući red iz NCI u CI kad identifikator preko kojeg se to radi nije unique?
Odgovor je prilično jednostavan: ako imamo non-unique CI, SQL Server će dodati još jednu kolonu u CI (tzv. uniquifier) i zatim u NCI prenositi ne samo vrijednost CI nego i taj uniquifier. Dakle, na umjetan način će "unikificirati" vrijednost clustered indeksa (da li je ovdje pravilno reći "unikificirati" ili "unificirati"?). Ta "unikifikator" kolona se ne može vidjeti kroz SELECT, nego samo korištenjem DBCC PAGE naredbe. Pored toga, ona je int tipa. Pa sad, ako imate CI na koloni koja ima vise od 2^31 (sasvim precizno, ne 2^31 nego 2.147.200.030) neke iste (kombinacije) vrijednosti u CI, onda imate problem, ne? I osobno, rekao bih da ga u tom slučaju i zaslužujete :))
Pozdrav, čujemo se.
Dean
*) Ne, ne mora nužno biti CI, ako postoji NCI koji je uži i kojem je pristup jeftiniji i preko kojeg se može zadovoljiti upit, optimizer se može odlučiti i za taj NCI. Obećavam post u kojem ću ovo demonstrirati.