INDEX(CLUSTERED,NONCLUSTERED)
2 çeşit index vardır.Clustered Index
ve NonClustered Index.
Kisi isminde bir tablo oluşturalım;
|
CREATE
TABLE Kisi
(
Id int,
[Name]
NVARCHAR(50)
)
|
Daha sonra bu tabloda Id kolonu
için CLUSTERED,[Name] kolonu içinde NONCLUSTERED Index oluşturalım;
|
CREATE
CLUSTERED INDEX
ci_KisiId ON Kisi(Id)
CREATE NONCLUSTERED
INDEX nci_KisiName ON
Kisi([Name])
|
Bir tablo üzerinde sadece ve sadece
1 adet CLUSTERED Index oluşturulabilir.NONCLUSTERED Index ise 249 tane olabilir.CLUSTERED
Index fiziksel olarak data page’leri Index’lerken,NONCLUSTERED Indexde mantıksal
olarak index yapısı oluşturur.
Index kullanımında B-Tree(Balanced
Tree) veri yapısı kullanılır.CLUSTERED Index’de aranılan veriye Index B-Tree içinde
ulaşılmış ise,asıl verilerin olduğu data page’e pointer vasıtasıyla gitmeye gerek
yoktur.Zaten CLUSTERED Index,asıl verilerin olduğu data page’ler baz alınarak oluşturulur.
Normalda index bulunan bir sayfada,bütün
verilerin bulunduğu data page’ler bir şekilde harddisk üzerinde konumlanmıştır.Bunun
dışında örneğin Id alanı için Index yapısı oluşturuluyor ise,data page’lerin haricinde
ayrıca bir B-Tree yapısı oluşturulur.Arama yapılacağı zaman öncelikle bu B-Tree
ağaç yapısı içindeki Index’lerde arama yapılır ve sonuç bulunduğunda
B-Tree üzerinde bulunan Node’un işaret ettiği Data Page’e gidilir ve asıl
veriler elde edilir.Fakat CLUSTERED Index’de bu durum geçerli değildir.Zira Data
Page’lerin kendisi zaten B-Tree yapısına uygun bir biçimde sıralanmıştır.Bu yüzden
Pointer vasıtasıyla asıl verilere yönlendirilme işi olmamaktadır.NONCLUSTERED Index’de
ise yukarıda anlattığımız senaryo geçerlidir yani data page’e pointer vasıtasıyla
geçiş yapılır ve veriler ordan elde edilir.
Bir tabloda bir Primary key varsa
bu genelde CLUSTERED Index’dir.Yani siz CREATE CLUSTERED INDEX komutunu kullanmasanız
bile,bir tabloda Primary key belirtti iseniz,o aynı zamanda CLUSTERED Index’dir.
Bir Index’i Disable etmek için şu
T-SQL komutu kullanılır;
|
ALTER INDEX ci_KisiId
ON Kisi Disable
|
Disable edilmiş bir key’i tekrar
aktif hale getirmek için şu T_SQL komutu kullanılır;
|
ALTER INDEX ci_KisiId
ON Kisi Rebuild
|
Bir Index’i uçurmak için ise şu
T_SQL komutu kullanılır;
|
DROP INDEX ci_KisiId
ON Kisi
|
Covering Index
Farzedelim Kisi tablosunda Ad ve
Soyad kolonlarının her ikisini NONCLUSTERED Index olacak şekilde ayarladık;
|
CREATE NONCLUSTERED
INDEX nci_Kisi ON
Kisi(Ad,Soyad)
|
Bu durumda B-Tree ağaç yapısı içerisindeki
her bir Node içinde hem Ad hemde Soyad bilgileri tutulacaktır.Index oluşturulduktan
sonra bir sorgu cümlesi gerçekleştirildi ve kişilerin ad ve soyadı alınmak istendi.Bu
durumda Kisi tablosunda yer alan diğer alanlara(TelNo,Fax,Email vs.) ihtiyacımız
olmayacaktır.Ad ve Soyad alanları ise zaten B-Tree içinde tutulmaktadır.Dolayısıyla
Index yapısında Ad ve Soyada göre ilgili kayıtlar bulunacak ve asıl Data Page’e
yönlendirme(pointer ile) yapılmadan veriler Data Page’lerden değil B-Tree içindeki
değerlerden elde edilecektir.İşte bu tarz index’lere Covering Index denilmektedir.
Balancing Index Maintenance
İyi,güzel,hoş...Madem aramalarımız
hızlanacak o zaman bütün tablolarımızda bütün kolonlar için Index tanımlayalım.Şöyle
düşünebilirim;her ne kadar bir tabloda en fazla bir adet CLUSTERED Index olabilsede
1 kolon için CLUSTERED, diğer kolonlar için ise NONCLUSTERED Index oluştururum ve
aramalarım acayip hızlı olur.
Her ne kadar doğru bir düşünce gibi
gözüksede,şöyle bir sorun vardır.Kisi tablomuzda 100 kayıt varsa ve biz Ad alanına
göre NONCLUSTERED Index oluşturmuş isek bu durumda 100 kayıt için B-Tree yapımıza
100 kayıt eklenecektir.Dolayısıyla her bir isim harddiskimizde 2 defa tutulacaktır.Ama
asıl problem verilerin 2 defa tutulması değil,B-Tree yapısına kayıt eklenme işlemidir.Sürekli
verilerin silindiği ve eklendiği bir Kisi tablosunda her bir kayıt ekleme silme
işleminde B-Tree ağaç yapısıda değiştirilmektedir.Öyle ki bir kayıt eklenmek istediğinde
eğer Node’lar içinde yer yok ise bu durumda Node bölünmesi olacak ve yeni Node eklenecek
ve bu Node bölünme işlemi belkide Root köke kadar gidebilecektir.Benzeri, kayıt
silme sırasında da olmaktadır.Bu işlemler ise karışık algoritmalar olduğundan dolayı,bu
işlemlerin her bir kolon için sürekli sürekli yapılması kayıt ekleme,silme aşamasında
performansı çok kötü etkileyecektir.Bunu dengelememiz gerekmektedir.En çok sorgu
yaptığımız alanlar üzerinden Indexleme yoluna başvurmalı ve tablomuzda 5’ten fazla
Index var ise bir dur demeliyiz ve
kontrol etmeliyiz acaba oluşturduğum indexler mantıklımı
değilmi diye.
Ama kayıt ekleme silme işleminin
yapılmadığı tablolarda,istatistiki verilerin tutulduğu ve çok nadiren değişen tablolarda
10 veya daha fazla Index oluşturmamızda bir problem yoktur.Çünkü yazma işleminin
getirdiği performans kaybı bizi etkilememektedir.
|