4 Aralık 2009 Cuma

Clustered Index Seçimi

Clustered Index seçimi tablolarımızdaki en önemli seçimdir diyebiliriz. Clustered Index, fiziksel olarak disk üzerindeki sıralamanın oluşturulmasında kullanılan clustered key veya clustered key'ler içerir. Detayını buradaki yazımda okuyabilirsiniz.

Peki Clustered Index seçerken nelere dikkat etmeliyiz, veya kesinlikle önerilen bir yöntem varmıdır dersek. Genel veritabanı kuralı olan duruma göre değişir lafı burada da geçerli :)

Öncelikle hangi tablolarda Clustered Index kullanmamalıyız konusunu aradan çıkaralım. Sürekli güncellenen veya tablolar arası taşıma durumlarının çok olduğu tablolarda Clustered Index kullanılmayabilir, bu sadece bir öneridir, uygun durum sistemden sisteme değişebilir, bu sebepten iki seçenekte denenerek daha verimli olan tercih edilmelidir. Bir diğer durum ise, büyük kolonlardan oluşan tablolarda her Non-Clustered Index için Clustered Index Key Logical RID kullanılacağından, index boyutları çok büyük olacaktır. Bu tür tablolarda da Clustered Index ve Heap denenmeli, daha verimli olan yöntem tercih edilmelidir.

Clustred Index kullanmaya karar verdiysek, şimdi hangi kolon veya kolonları seçmemiz gerektiğine karar vermemiz kalıyor geriye.

Örneğin çok sayıda INSERT alan tablolarda yeni gelen kaydın tablonun en altına eklenmesi genellikle tercih edilen bir yöntemdir. Bu durumda giderek artan değerlerden oluşan bir Clustered Index yapısı tercih edilebilir. Bu tür bir seçimde seçilen key'in Unique olup olmaması konusuda önemlidir, onun detaylarını da buradan okuyabilirsiniz.

Clustered Index key güncellenen bir kolon olmamalıdır. Bu her güncelemede kaydın fiziksel olarak yer değiştirmesi demektir, bu hem performansı çok kötü etkileyecek hemde index üzerindeki fragmantation'ı arttıracaktır.

Clustered Index, disk üzerindeki fiziksel sıralama demek olduğundan, BETWEEN, >, >=, <, <= gibi sorgu filtreleri eğer Clustered Index Key üzerinden sorgulama yaparlarsa SQL kaynak kullanımı en alt seviyede olacak ve disk üzerinden fiziksel okuma ile kayıtlar çok hızlı elde edilebilecektir. Clustered Index Key aynı şekilde Sort işlemlerinde kullanıldığında, veriler zaten sıralı olduğundan ek bir işleme gerek kalmayacaktır. Group By kullanımında gene sıralı verilerin gruplanması çok daha hızlı olacaktır.

Bu bilgilerin dışında ben kişisel olarak, bu tabloların ne kadar sürede bakım görecekleri ile de çok ilgilenirim. Uygun şartlarda veritabanları haftada bir veya en azından iki haftada bir bakımdan geçmelidir. Ancak benim çalıştığım neredeyse hiç bir şirket bu şekilde bir bakımı düzgün olarak yapmamaktadır. Index yapıları bozulduğunda index'ler sisteme destek değil köstek olmaya başlarlar. Fragmantation değerlerinin %10'lara geldiği nice kritik kullanılan tablo görmüşümdür ve bu şirketler günde yüzbinler veya bazen milyonlarca transaction alan şirketler. Bakım yapmama konusunda inatçı veya umursamaz olan müşterilere veritabanı tasarlarken Clustered Index Key kesinlikle artan bir değer olmalıdır diyebilirim. Non-Clustered Index'ler bozulduğunda buna yapabileceğimiz birşey yok ama en azından bu şekilde Clustered Index'lerin bozulmamasını sağlamış oluyoruz.

Düzgün bakım yapıldığını varsayarak ilerlersek. Az INSERT alan tablolarda INSERT maliyeti kesinlikle ihmal edilmelidir. Yani müşteri bilgilerini tutan bir tablo ile müşterilerin satın alma bilgilerini tutan tablo aynı şekilde değerlendirilmemelidir.

Bir bankayı düşünelim, sizce bir banka günde kaç yeni müşteriyi veritabanına ekleyebilir. Bir de şunu düşünelim, bu bankanın tüm müşterileri bir günce kaç kredi kartı işlemi yapabilir. Bu şekilde düşündüğümüzde sürekli INSERT alan ve az INSERT alan tabloları kafamızda canlandırabilmiş oluyoruz.

Bankamız eğer müşteri numarası ile işlemleri yapıyorsa MüşteriNo alanımızı Clustered Index Key olarak seçebiliriz, ama genellikle isim ve soyad bilgisi ile sorgularımızı yapıyorsak o zaman burada İsim ve Soyad alanları beraber Clustered Key Index olarak seçilebilir. Bu şekilde isim ile yapılan aramalarımız çok daha hızlı sonuçlanacaktır. Soyad bilgisinin isme göre daha değişken olduğunu da düşünürsek Soyad ve İsim sırası ile Clustered Key Index oluşturmamız daha da mantıklı olacaktır. Buradaki amacımız isim ve soyad ile yapılan aramalarda en üst performansı almaktı ve bunu başardık. 
Peki dezavantajlarımız neler oldu?
Öncelikle Soyad ve İsim Unique değildir, bir çok kişi aynı Clustered Index Key'e sahip olacaktır, SQL bunu engellemek için uniquifier denilen 4 byte'lık bir görünmez kolonu Clustered Index'imize ve dolayısıyla tüm Non-Clustred Index'imize ekleyecektir.
Tablomuza az da olsa yeni eklenen kayıtlar sıralı olmadığından, fiziksel olarak diğer kayıtların aralarına girmek durumunda kalacak, kayıt kaydırma işlemleri başlayacak ve tablomuzda fragmantation oluşacaktır, bunu engellemek için düzenli bakım yapmamız ve fill factor değerini yüksek tutmamız gerekecektir.

Peki sırayla artan bir Müşteri No bizim Clustered Index Key'imiz olsaydı ve Soyad İsim alanına Non-Clustered bir index tanımlamış olsaydık olmaz mıydı?

Olurdu, bu şekilde uniquifier alanına gerek kalmazdı ve Clustered Index fragmantation derdimizde ortadan kalkardı, müşteri no ile gelen sorgular çok hızlı olurdu ve sıralı çok sayıda müşteri numarasını çok hızlı bir şekilde sorgulayabilir, gruplayabilir ve sıralayabilirdir.

Kısacası bunlar bizim tercihlerimiz ile ilgili. Bizim tercihlerimizi de sistemin kullanılma şekli, ve sistemden beklelenlerin öncelikleri belirlemeli. Burada ilk başta yapılan tasarım daimi olacak diye bir kural yok, yaptığımız hatanın farkına varınca gerekli değişiklikleri yapma şansımız olabilir, sonuçta bazı durumlar denenmeden bilinemiyor.

Sürekli çalışan sistemlerdeki tablolara dokunmak son derece zor veya bazen imkansız olabiliyor, bu tür durumlarda SQL 2005 ile gelen ve çeşitli durumlarda kullanılabilen ONLINE ve MAXDOP parametrelerini araştırmakta fayda var.

Hiç yorum yok:

Yorum Gönder