SQL Server 2005 - Hızlı El Kitabı
Skip Navigation Links.

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.