3 Aralık 2009 Perşembe

Clustered ve Non-Clustered Index

Index'ler konusuna gelirsek iki index örneğimiz var, clustered index bir anlamda tablonun kendisi demek, non-clustered index ise, kabaca belirli alanların direk clustered key ile eşleştirilerek tüm tablonun taranmasına engel olmak demek diyebiliriz. Yazımın sonunda basit bir örnek vereceğim.

Detaylara girmeden önce sıkça kullanılan bir kısaltma RID : Record ID anlamına gelir. İki türlü karşımıza çıkar, Physical ve Logical. Bildiğim kadarıyla Physical RID disk bilgisini içerirken, Logical RID clustered index bilgisini içerir.

Heap : Bir tabloda eğer clustered index yoksa bu tabloya heap diyebiliriz. Bu tablolarda bir kaydı bulmanın tek yolu full table scan yapmaktır. Pek rastlanmaz ama, tablomuzda clustered index yok ama non-clustered index var diye düşünürsek, SQL her non-clustered index kullanımında table scan yapmaktansa, non-clustered index'in heap üzerindeki Physical RID ile eşleştirir. Bu non-clustered index key için kullanılacak olan satır bu disk alanındadır şeklinde bir işaretleme olarak düşünebiliriz bu durumu.

Clustered Index: Disk üzerinde fiziksel olarak tablodaki kayıtların sıralanmasını sağlayan index'tir, aslında tablonun kendisidir de diyebiliriz. Buradaki sıralamayı sağlayan alana cluster key diyebiliriz. Cluster key olabiliyorsa unique olmalıdır. Ancak bazı durumlar için bu şekilde bir yapı kullanılamayabilir. Non-Unique Clustered Index Kullanımı için buradaki yazımı okuyabilirsiniz. Clustered index ve non-clustered index barındıran tablolarda, non-clustered index'ler clustered index'lerin Logical RID bilgisini tutarlar. Heap durumunda bu Physical RID idi. Bu non-clustered index key için kullanılacak olan satır bu Logical RID ile eşleşen clustered index alanındadır diye bunu düşünebiliriz. Clustered index zaten bulunduğu disk bilgisine sahiptir ve bu şekilde uygun disk alanına ulaşılır. Clustered index eğer araya kayıt alırsa disk üzerinde belirli kaydırma işlemleri yapmak durumunda kalacaktır, bu kaydırma işlemlerini, clustered index disk bilgilerinin güncellenmesi olarak düşünebiliriz. Non-clustered index'ler disk alanı (Physical RID) ile değil, clustered index'in Logical RID bilgisi ile eşleştiği için, bu kaydırmalarda non-clustered index'ler etkilenmezler.
Heap kullanımında ise emin olmamakla beraber sanırım bütün yeni kayıtlar disk üzerindeki son tablo kaydının sonrasına aktarılır. Zaten kayıtlar için belirli bir sıra gerekmediğinden yeni kayıt, son kayıt ardına yazılır ve bir kaydırma işlemi olmaz. Yani ben yapsam böyle yapardım :)

Heap ve Clustered Index arasındaki bir fark da Read performansındadır. Clustered Index üzerinde kayıtlar sırayla bulunduğundan dolayı, Heap'e kıyasla 8 kat daha hızlı veri okunabilir. Bunu güzel ama eski bir yazıdan okumuştum, yeni SQL versiyonları ile bu değerler değişmiş olabilir. Kaynak.

Basit bir örnek vermeyi deneyeyim;
Can diye bir müşteri olsun ve bu müşterinin 1000 tane alış işlemi olsun, oldukça iyi bir müşteri :)
Alım işlemleri tablomuzda 20.000 işlem olsun, ve işlem numaramız bizim clustered key alanımız olsun. Örneğimizi basit tutmak için müşterilerin de isimle bu tabloda tutulduğunu varsayalım. 
Bu durumda 5 numaralı alım işlemini bulmak istediğimizde clustered index scan yaparak SQL olabilecek en hızlı şekilde bize kayıt bilgilerini dönecektir.

Can'ın işlemlerini bulmak istediğimizde, sistem tüm tabloyu tarayacak ve 20.000 kaydı inceledikten sonra bulduğu kayıtları işlem numarası ile eşleştirerek yukarıdaki senaryodaki gibi devam edecektir. 

Peki biz Can'ın isim bilgisinin olduğu alana bir non-clustered index eklersek ne olacak? Gene 20.000 kaydı incelemeyecek miyiz?
Cevap hayır, sebebi ise non-clustered index alanlarının sıralı olarak saklanıyor olması. Kabaca düşünürsek ismi C ile başlamayan kayıtların SQL'in incelemesine gerek kalmayacaktır. Gene kabaca düşünürsek; tabloyu tararken D harfine geldiğimizi varsaysak devam etmemize gerek kalmacayaktır.

3 yorum:

  1. Can Bey merhabalar,
    Indexing ile ilgili tüm yazılarınızı okudum.
    Olayın mantığını tam anlamıyla kaptığım bu yazı başta olmak üzere, konuyla ilgili tüm yazılarınız için teşekkürlerimi sunarım.
    İyi çalışmalar...

    YanıtlaSil
  2. Ben teşekkür ederim.

    YanıtlaSil
  3. Sonunda oturdu Teşekkürler Can

    YanıtlaSil