Clustered Index vs Non-Clustered Index
Tablo üzerinde bir veri araması yaptığımızı varsayalım. Veritabanında saklanan verilerin sayısı arttıkça bu performansta düşüklüğe neden olur. Dağınık yapıda olan verilerde istenilen veriyi aramak için tablo taraması işlemi yapılır. Sql’de indexe sahip olmayan tablolara heap adı verilir. Heap bir tabloda bir select çektiğimizde, sql tablodaki kaydı bulabilmek için bütün kayıtları bir bir dolaşır. Hatta kaydı bulsa dahi, birden fazla kayıt olma ihtimaline karşı tabloyu dolaşmaya devam eder. Bu da sql için ciddi bir performans kaybına yol açar. Bu işlemi küçük boyutlu bir tabloda yapmak kolaydır. Ancak artan veri miktarına göre bu işlem vakit kaybettirir. Indexler ise tablolardan veri çekmek için gerekli sorgular çalıştırılırken gereken süreyi azaltmak için kullanılırlar. İşte tam da bu noktada , sorgu işlemlerimi yaparken clustered index ve non-clustered index kavramlarını bilmemiz sql performansı açısından işimize yarayacaktır.
Yukarıda bahsi geçen olayı somut bir şekilde örnekleyelim.
Create table [tblEmployee] ( [Name] nvarchar(50), [Salary] int, [Gender] nvarchar(10), [City] nvarchar(50) )
Tablomuzda aşağıdaki gibi binlerce hatta yüzbinlerce kayıt olduğunu varsayalım. Bu tabloda kayıtları spesifikleştiren hiç bir index bulunmamaktadır. Bu yüzden insert durumunda kayıtlar tamamen free olarak tabloya yerleşir. Bu gibi tablodan select * from tblEmployee where Name = ‘Tobb’ şeklinde bir select attığımzda , sql kolonları unique yapacak bir veriye sahip olmadığı için 1. kayıttan itibaren sırayla Name’i Tobb olan kaydı aramaya başlar. Bu tip arama işlemine scan denir. Bulsa dahi birden fazla Tobb isimli kayıt olup olmadığını bilmediğinden, aramaya devam eder. Al sana performans problemi 🙂
insert into tblEmployee values('Sam',2500,'Male','London') insert into tblEmployee values('john',2500,'Male','London') insert into tblEmployee values('Tobb',2500,'Male','London') insert into tblEmployee values('Crixus',2500,'Male','London') ...
Problemi anladıysak artık bu gibi performans kayıplarına düşmemek için Clustred index ve non-clustred index kavramlarına geçiş yapabiliriz.
Clustred Index
Clustred index , veriyi sql’de fiziksel olarak sıraya sokan yapıdır. Aslında hepimiz clustred index’i tablolarımızda kullanıyoruz. Tablolarımıza tanımladığımız her bir Primary key aslında otomatik olarak bir Clustred index yapısıdır. Çünkü tablolarımız bu pk’ya göre fiziksel olarak sıralanır.
Yukarıdaki tablo yapısını tekrardan primary key ile oluşturalım.
Create table [tblEmployee] ( [Id] int Primary Key, [Name] nvarchar(50), [Salary] int, [Gender] nvarchar(10), [City] nvarchar(50) )
artık tablomuz bir clusted indexe sahip. Bunu somut olarak görebilmek için aşağıdaki sorguyu çalıştıralım.
Execute sp_helpindex tblEmployee
Şimdi tablomuza insertlerimizi yeniden atalım.
insert into tblEmployee values(3, 'Sam' ,2500,'Male' ,'London') insert into tblEmployee values(1, 'john' ,2500, 'Male' ,'London') insert into tblEmployee values(2, 'Tobb' ,2500, 'Male' ,'London') insert into tblEmployee values(4, 'Crixus' ,2500, 'Male' ,'London') ...
bu insertlerin atılış sırası ne olursa olsun sql bunları otomatik olarak clustered index olan Id’ye göre dizecektir. Ve hedefe yönelik bir search ile index üzerinden hızlı bir şekilde bulunabilecek hale gelecektir.
Clustered index ile ilgili önemli noktalar
- Her tabloda yalnızca 1 adet clustered index olabilir.
- Sql query sonucu sıralı dataları dönerken de clustered indexe göre aynı sırada döner.
- Tablodaki bir clustered index pk olabileceği gibi aynı zamanda birden fazla kolonun birleşiminden oluşan bir yapı da olabilir. Buna composite clustered index denir.
Aşağıdaki query ile 2 kolona bağlı clustered index yaratmış olduk. Bu query’nin bize söylediği şey, tablomdaki kayıtları Gender’a göre diz , genderi aynı olanları da artan sırada salary’e göre diz. Siz insertlerinizi ne şekilde atarsanız atın, dizilim bu yönde olacaktır.
create clustered index myClusteredIndex On tblEmployee (Gender Desc,Salary Asc) Drop index tblEmploye
Primary key – Clustered Index farkı nedir?
Tam bu noktada kafa karışıklığını önlemek için primary key ve clustered indexin farkını netleştirmek istiyorum. Primary key dediğimiz, tablodaki kaydın uniqueliğini garantileyen bir alandır ve kaydın kimliğidir. Tanımlandığı gibi de clustered index özelliği taşır. Peki clustered index nedir? Yukarıda da anlattığımız gibi bir veri yapısı, dataya daha hızlı ulaşmak için oluşturulmuş bir indexleme şeklidir.
Genel olarak datanın fiziksel sıralamasını düzenleyerek dataya ulaşma süresini optimize etmeyi amaçlarken, keyler ise datanın uniqueliğini sağlar.
Non-Clustered Index
Non-clustered indexlemede durum biraz daha farklıdır. Bir kolonu Non-clustered index olarak indexlediğinizde, arka tarafta yeni bir tablo oluşur ve bu tablo sizin indexlediğiniz kolona karşılık kolon adresini tutar. Yani bir nevi pointer yapısı gibi düşünebilirsiniz. Non-clustered indekste verilere direkt erişilemez. Elde edilen indeksleme yapısına erişmek için kümelenmiş indeks yapısı kullanılmış olur. Verileri herhangi bir alana göre sıralandığında erişim kümelenmiş indeks üzerinden anahtar değer referans alınarak yapılır.
Non-cluster indexlemeyi kafanızda oturtabilmek için klasikleşmiş kitap örneğini düşünebilirsiniz. Kitapların başında içerik kısmı vardır. Bu içerik kısmında her bir konu başlığının hangi sayfa numarasında veya sayfa numaraları aralığında olduğunu gösterir. Siz kitabı açtığınızda önce içerik sayfasına bakarsınız. Daha sonra aradığınız içeriğin sayfasını ya da sayfa aralığını öğrenip direkt olarak bu sayfalara geçersiniz. Non-cluster index de tam olarak bunu yapmakta.
Non cluster index oluşturmak için aşağıdaki sorguyu kullanabiliriz.
create nonclustered index myClusteredIndex On tblEmployee (Gender Desc,Salary Asc)
Non clustered index ile ilgili önemli noktalar
- Bir tablonun birden fazla non-cluster indexi olabilir.
- Bir tabloya non-cluster index eklemek, tablonun fiziksel dizilimini etkilemez.
Çağatay bey yararlı bilgiler için teşekkür ederim