msHOWTO

3 Mayıs 2012 Perşembe

Sql Server Index Yapısı

Merhaba arkadaşlar.Bu makalemde sizlere index nedir? Nasıl bir yapısı vardır ? Ne gibi yararlar sağlar ? Nasıl kullanılır ? Neden kullanılır ? gibi detaylı olarak index yapısını anlatacağım.Eğer bu makaleyi okuyorsanız ya küçük veya orta çaplı database ler ile çalıştınız yada verilerinin oldukça birikti sorgularınız geç cevap veriyordur.Açıkça söylemek gerekirse ben index lerin ne olduğunu büyük database lerle çalışmadan bilmiyordum.Ta ki bir gün bir projede database deki birden fazla tablonun içerisindeki kayıtların yüzbinleri hatta milyonları bulabileceği söylenene kadar.İlk yaptığım hemen 3 kolonlu basit olarak adı ve soyadı bilgilerini tutan bir tablo oluşturmak oldu.Daha sonra basit bir while döngüsü ile 1.000.000 kayıt girdisi yaptım.Sonrasında ise sadece select * from adi where adi='koray99999' şeklinde bir sorgu çekmek oldu.Bakın ne join yapısı var ne sub query filan var.Basit bir sorgu.Dedim en fazla 2-3 saniyede getirir sonucu dedim.Fakat hiç de öyle olmadı :).Oldukça fazla beklemiştim.Dedim bu böyle olmaz.Mutlaka bir yolu yöntemi vardır.Araştırmalarım sonucunda index nimetini buldum.Index yapısını oluşturduktan sonraki sorgumun sonucu bana 1-2 saniye gibi müthiş bir hız farkıyla döndü.Bu bizzat benim yaşadığım örnekti.Bir de düşünün arkadaşlar turkcell avea gibi telefon şirketlerinin database lerini ve bu databaselere gelen sorguları ? Yani kısacası eğer veriniz oldukça fazla ise yada en azından bunu öngörebiliyorsanız yüksek performans almak zorundasınız.Bunun için de index yapısı oluşturmalısınız arkadaşlar.Index'in faydasını anlattıktan sonra hadi gelin Index in yapısını inceleyelim.

Sql server'da 2 farklı index yapısı mevcuttur.Clustered ve Non-Clustered Index.

1-)Clestered Index:Kümelenmiş index olarak türkçeye çevirilebilinir.Diyelim ki arkadaşlar özel bir dershane açtık.İlk gün 10 tane öğrenci geldi kayıt ettik.Bu öğrencilerin dosyalarını çekmeceye koyduk.2.gün 15 öğrenci kaydoldu ve bu öğrencilerin dosyalarını da çekmeceye koyduk.İlk hafta sonunda toplam 60 öğrencimiz oldu.Çekmecemiz doldu bu sefer de dolablara koymaya başladık.Bu şekilde durumu kurtardığımızı düşündük.Fakat yıllar geçti bu sefer dolaplarda yetmedi hatta arşivlemeye başladık.Yer sıkıntımız oluştu.Hatta bir gün Koray Düzgün adında bir öğrencimizin bilgisine ulaşmak istedik.O kadar veri yığınının içinde ara ki bulasın.Bundan bir ders çıkardık ve alfabetik sıraya göre sıralayıp tüm dosyaları kümeleştirdik.Bir sonraki öğrenci geldiğinde direk hangi kümedeyse hangi sıradaysa gidip bulduk.Ne kadar hızlı sonuca ulaşıp ne kadar iş ve zaman kazancı sağladık.İşte arkadaşlar database imizdeki verilere clustered index yapısı oluşturursak aynı şekilde kazanç sağlarız.Clustered index yapısında elimizdeki veriler sıralı olarak belli bir grup içinde bulunur.Bu şekilde çok daha hızlı bir şekilde sonuca ulaşırız.Aslında eğer veri tabanı oluşturduysanız daha önce farkında olmadan kesinlikle eminim ki clustered index kullandınız.Hepiniz bir tabloda bir kolona mutlaka primary key koymuşsunuzdur.Hatta identity bile verdiniz.Identity verdiğiniz anda o kolondaki veriler sıralı olarak kaydedilmiyor mu ? Alın size işte clustered index.Clustered index 3 yapıdan oluşur.


Clustered index yapıldığında sıralanan veriler leaf de tutulur.Yukarıdaki örnekte öğrencinin dosyasına ulaştığınızda direk verinin kendisine ulaşıyoruz değil mi ? Bunun nedeni de clustered index de veriler leaf aşamasında bulunur.Baş harflerine göre gruplama yaptığımızda ise bu grup bilgileri de intermadiate level larda tutulur.Bilinmesi gereken en önemli noktalardan birisi bir tabloda sadece 1 tane clustered index oluşturulabilinir.

2-)Non-Clustered Index:Bir kitap aldınız elinize.Oldukça kalın bir kitap.Diyelim ki sql server ile ilgili bir kitap olsun.Ve index konusunun geçtiği sayfaları tek tek bulmak istiyorsunuz.Ne yaparsınız?Bütün kitabı arayıp bulur musunuz? Yok artık . Bazı kitaplarda sonlarında içinde geçen konular ve bu konuların ve ya kelimelerin sayfa numaraları liste halinde yazılıdır.Ne yaparsınız böyle bir durumda?Öncelikle gidip arkadan hangi sayfalarda olduğunu bulursunuz.Daha sonra o sayfalara bakıp veriye ulaşırsınız.İşte en güzel non-clustered yapısı.Bu örnekten de anlaşıldığı gibi non-clustered yapıda verinin kendisine ulaşamazsınız.Bu yapıda leaf level larda verinin bulunduğu adres bulunur.Daha sonra tekrardan root a çıkılıp aşağıya doğru inilerek verinin kendisine ulaşılır.Sql server 2005 de 255 tane bir tabloya non-clustered index oluşturabiliyorduk.Sql server 2008 ile birlikte 999 adet oluşturulabiliniyor.Fakat pek tabi bir tabloya bu kadar non-clustered index verilmez.Ben bolca var nasılsa her kolona koyayım oh ne güzel gibi bir düşünce olmasın.Çünkü bu sefer index yapısı arka planda karışıyor.Dikkat edilmesi gereken şu ki en fazla sorgu çekilen kolonlara verilmek en doğrusudur.

Clustered yapılarını kavradıktan sonra bakalım tüm bu anlatılanlar ne kadar doğru ? Hemen test yapalım arkadaşlar.


DECLARE @i INT
SET @i=0
WHILE(@i<100000)
BEGIN
INSERT INTO dbo.Telefonlar
SELECT Ad='Koray'+CAST(@i AS nvarchar(30)),SoyAd='Düzgün'+CAST(@i AS NVARCHAR(30)),TelefonNo='123456789'
SET @i=@i+1
END

T-Sql kodları ile verilerimizi kaydettik.Daha sonrasında ise ,

--Aşağıdaki işlemle Kaç logical read yaptıgımı gösteren sistemi açtým
SET STATISTICS IO ON

-- Aşağıdaki  işlemle Kaç Kaç milisaniye geçtiğini gösteren sistemi açtým
SET STATISTICS TIME ON

Daha sonra ise 

SELECT * FROM dbo.Telefonlar WHERE Ad='Koray99993'

Olarak select çekin.Ve çıkan verilere göz atın.Daha sonra ise 

--Clustered indeks tanımladım

CREATE CLUSTERED INDEX TelefonIndeks ON dbo.Telefonlar(AdresID)
SELECT * FROM dbo.Telefonlar WHERE AdresID=80000



Olarak select çekin.Ve çıkan verilere göz atın.Daha sonra ise 

REATE NONCLUSTERED INDEX AdaGoreIndeksle ON dbo.Telefonlar(Ad)

--Non-Clustered indeks tanımladım

SELECT * FROM dbo.Telefonlar WHERE Ad='Koray99993'

Olarak select çekin.Ve çıkan verilere göz atın.Sonuçlardan farkı göreceksiniz.

Umarım faydalı olmuştur arkadaşlar.Bir sonraki makalemde görüşmek dileğiyle...



3 yorum:

  1. Çok teşekkürler elinde bir proje vardı sanırım sorunumu çözer. İlk zamanlar hiç bir problemin yoktu fakat sonradan sistem yavaşlamaya başladı. Bir işlem tamamlanmadan diğerine geçmeyen bir sistem yazılı, bazen öyle bir yığılıp kalıyorki işlemler komple bağlantıları kapatmam gerekiyordu. Tekrar teşekkürler.

    YanıtlaSil
  2. Faydalı olduysa ne mutlu ... Fakat index yapısı çok dikkatli ve önemle yapılmalıdır..Aksi takdirde çok daha kötü performans alabilirsiniz.Dikkatli ve detaylı düşünerek yapınız ... Saygılarımla

    YanıtlaSil
  3. Merhaba,
    Diyelimki "...WHERE adi='Koray' AND soyadi='Düzgün' şeklinde bir SELECT sorgumuz var. Indexleme mysql'de tek sutun için yapıldığı gibi iki sutunu aynı anda da yapılabiliyor. Acaba bu şekilde bir sorgu için ad'i ayri soyadi'ni ayrı indexlemek mi daha doğru yoksa adi ve soyadi alanını beraber bir kerede indexlemek mi daha doğru?

    YanıtlaSil