SQL Server Index Yapilari : Index Nedir, Index Çesitleri

SQL Server Index Yapilari : Index Nedir, Index Çesitleri

Bir kitapdaki fihrist(index) yapisi gibi veritabaninda bulunan bir indexde, bir tablodaki veya indexed viewdeki belirli bir veriyi hizli ve kolayca bulmamizi saglar. Index tablo veya viewdeki bir veya daha fazla kolon üzerinde bir anahtar üretir ve bu anahtar bu verinin saklandigi yeri direk olarak isaret eder. Iyi dizayn edilmis index yapilari ile veritabani sorgularinizi veya uygulamalarinizi gözle görülür seviyede hizlandirabilirsiniz. Indexler sorgu sonucu getirilecek veriye ulasmak için gerekli olan veri okuma boyutunu büyük ölçüde azaltirlar. Ayrica indexler ile tablodaki her satirin tekil olmasida zorlanabilir.

.

Indexin Temelleri:

Indexler bir tablo veya viewde bulunan kayitlari hizlica getirmemizi saglarlar. Index tablo veya viewdeki bir veya daha fazla kolon üzerinde bir anahtar üretir. Bu anahtarlar yapisal olarak (B-Tree) saklanirlar ve SQL Serverin bir satira kolayca ulasmasini saglarlar.

Bir Tablo veya View Asagidaki Index Türlerini Içerebilir.

Clustered Index

Clustered indexler tablo veya viewlerin satirlarinda bulunan verileri olusturdugu anahtarlara göre sirali bir sekilde tutar ve bu siraya göre disk üzerinde tutarlar. Bu anahtarlar index yapisinda bulunan kolonlardan olusurlar. Bir tablo için sadece bir adet clustered index tanimlanabilir, çünkü tablodaki veriler diskte tek bir siraya göre tutulabilirler. Kisacasi clustered indexler tablonun aslinda kendisidir diyebiliriz. Tablodaki tüm verileri anahtara göre diskde siraliyarak tuttuklari içinde birden fazla clustered index eklenebiliyor olmasi verinin tekrarlanmasi anlamina geleceginden, sadece tek bir clustered index kullanilabilir.

Bir tablodaki verilerin disk üzerinde sirali olarak kaydedilmesi için clustered index barindirmasi gerekir, Eger bir tablo da clustered index yoksa tablodaki veriler diske rastgele kaydedilir. Clustered index bulunan bir tablo clustered table diye adlandirilir. Clustered index olmayan bir tablo ise heap diye adlandirilir. SQL Serverda Actual Execution Plan üzerinde inceleme yaparsaniz heap veya clustered table gibi tanimlarla karsilasabilirsiniz.

Nonclustered Index

NonClustered Indexler de bir veya birden çok kolonu barindirirlar ve bu kolonlarin bulundugu rowlarin diskde bulundugu yerleri isaret eden isaretçiler bulundururlar.

NonClustered Index tarafindan rowlari gösteren isaretciye row locator denir. Row locator yapisi verinin bir heap demi yoksa clustered tabledami oldugununa göre degisir. Heap için row locator tablodaki rowu gösterirken Clustered table için ise clustered index anahtarini gösterir.

Clustered ve nonClustered indexlerin her ikiside tekil olabilirler. Bunun anlami hiç bir row birbiri ile ayni index anahtarini barindirmaz. Aksi takdirde birden çok row ayni index anahtarini paylasirlar.

Remark Indexler tablodaki veriler degistigi zaman otomatik olarak güncellenirler.

Remark Bir tabloda PRIMARY KEY ve UNIQUE kolon eklendigi zaman bu kolonlar için veritabani motoru otomatik olarak bir index olusturur.

.

Indexler Query Optimizer tarafindan nasil kullanilirlar:

Iyi dizayn edilmis index yapilari diskdeki I/O operasyonunu azalttiklari için daha az kaynak kullanarak veriye ulasmamizi saglarlar, bu yüzden sorgu performansinda artis saglarlar. Indexler; SELECT, UPDATE, DELETE veya MERGE gibi ifadeleri barindiran sorgular için oldukça faydalidirlar. “Select PersonelAdi, IseGirisTarihi from Personel where PersonelID = 13” sorgusunu çalistirdiginizda query optimizer bu sorgu sonucu üretilecek veriye ulasmak için kullanabilecegi tüm metodlari listeler ve en hizli ve etkili kullanabilecegi metodu seçer. Bu metod bir table scan(tabloyu tamamen okumak) olabilecegi gibi bir veya daha çok index üzerinden tarama islemide olabilir. Ikinci metod sadece indexiniz varsa çalisir.

Eger table scan islemi yapilirsa, query optimizer tüm kayitlari olur ve where cümlesinde yazdigini kritere uygun olan kayitlari bulur. Tüm tabloyu okudgu içinde table scan islemi disk üzerinde çok fazla I/O operasyonu olusturacaktir. Eger sorgu sonucu gelecek kayit sayisi tablodaki tüm kayit sayisinin büyük bir kismini kapsiyorsa bu durumda table scan metodu etkili ve basarili olacaktir.

Query optimizer bir index kullanacak olursa, tablonun tamammi yerine sadece index üzerinde arama yapar ve eslesen anahtarlar yardimi ile direk olarak verinin bulundugu yere giderek verileri okur. Genellikle index üzerinde okuma yapmak, tabloyu tamamen okumak(table scan) yapmakdan çok daha kolay ve hizli olacaktir, çünkü index az sayida kolon barindirir ve barindirdigi kolonlar için ürettigi anahtarlari sirali bir sekilde tutmaktadir.

Query optimizer bir sorgu çalistirdiginiz zaman en etkili yöntemi seçecektir, eger bir indexiniz yoksa mecburen table scan yapacaktir. Sizin göreviniz kullandiginiz sorgulara göre en iyi seklde index yapilarini olusturmak, böylece query optimizer index kullanmaya karar verdigi zaman olusturduginiz indexler içindede en hizli olacak olan bir indexi veya birden çok indexi seçebilir. SQL Server kullandiginiz sorgulara göre bir tabloda hangi alanlara index atmaniz gerektigi konusunda yardimci olmak için Database Engine Tuning Advisor adinda bir araç barindirir. Bu araci kullanarak index olusturma konusunda yardim alabilirsiniz.

Bir sonraki makalemizde bahsettigimiz indexleri nasil olusturabilecegimizi ayrica index olustururken dikkat etmemiz gereken kriterlerin neler olduguna deginecegiz.

.

Tags:

11 thoughts on “SQL Server Index Yapilari : Index Nedir, Index Çesitleri

  •  Eger SSAS kullanmiyacaksaniz. SQL de index yapilari ve partionlari olusturduktan sonra yapabileceginiz tek sey fiziksel yapiyi kuvvetlendirmek. Disk yapilarini ve ram miktarlarini arttirmakla baslamalisiniz. Tablodaki verileri uygun bir yapida partionlara bölün. Her partion için filegrouplari farkli ve hizli disklere koyun. Bu durumda veriler gruplanirken paralel olarak çok daha hizli gruplanacak ve süre çok düsecektir.

    Ayrica CPU sikintiniz yok ise verileri compress edin. Böylece I/O miktarini düsürerek CPUdan kaybinizdan daha fazlasini I/O dan kazanabilirsiniz.

  •  Anladim hocam cok saolun

    SSAS olmaz ama artik bir caresine bakacagim. 

    Iyi calismalar

  • distinct count islemi gerçekten çok fazla kaynak tüketir. Biz bu tür sorgulari 4-5 milyar kayit bulunan tablolarda çalistiriyoruz. 30 dakika civarinda geliyor. Fakat makinamiz biraz buyuk.

    Eger bu sorgu sonuu üretilecek veriyi rapor olarak düzenli vereceksen kesinlikle SSAS ile küp yap ve ordan sun derim. 

  •   Dediklerini aynen yaptim daha once hocam ama pek degisiklik olmadi 

    , aslinda bu sorrguya daha fazla yapacak biseyde aklima gelmiyor 
    senin dediklerinde onu gosteriyor, daha ne yapabiliirmki ama 
    cok zaman aliyor. bi sekilde dusurulmesi lazim 🙂  
    Inner join olabilir ama ondada From dan sonraki tabloda 
    isime yarayan bazi ID ler gelmeyecek oda olmayacak.  En cok kaynagi 
    tuketen su hesaplama Exe.Planda oyle gorunuyor. " Count_App
  • tabloda 12 miyon kayit var ve sen distinct count atiyorsun. bu durumda sorgunun 5-10 dakikada bitmesi gerçekten cok zor. SQL Server makinasinin ram ve disk özellikler ayrica core sayisi cok belirleyici bu durumda.

    count çektigin kolonlara non clustered index at. bu bir nebze daha hizli donus saglar. 2 tabloda join için kullandigin kolonlara index at. eger iki tablo inner join ile baglandigi zaman veri kaybin olmuyor ise left yerine inner join kullanmam daha hizi sonuc getirir.

    Sorgunu amaci ve kullanim yerini bilmiyorum eger surekli olarak bu sekilde rapor vereceksen bence bu verilerden bir SSAS küpü olustur. küp ile bu tür verileri çok daha hizli alabilirsin.

     

  •  

    SELECT  f.DevID, FirstTime= CASE WHEN COUNT(distinct f.InsId ) = 1 THEN ‘YES’ELSE ‘NO’ END,Count_Ins= COUNT(distinct f.InsIs), Count_App = COUNT(distinct f.AppId) , Max_InsDate ,Platform= MAX(APP.[PartName])  INTO #Temp_Installation FROM Fct_Ins f (NOLOCK) LEFT JOIN Dim_Apx APP (NOLOCK) ON APP.AppId = f.AppId  GROUP BY f.DeviceID Kusura bakmayn karakter sigdiramadim

     

  • Devami soyle

    SELECT f.DevID, FirstTime = CASE WHEN COUNT(distinct f.InsId ) = 1 THEN ‘YES’ELSE ‘NO’ END,Count_Ins= COUNT(distinct f.InsIs), Count_App = COUNT(distinct f.AppId) , Max_InsDate ,Platform = MAX(APP.[PartName])  INTO #Temp_Installation FROM Fct_Ins f

  • oyle where kosulu sorgularda kolayda , karisik bir sorgum var 12M donderiyor , sorgu aynen soyle isimerini degsitirdim sadece bu sorgu 1 saaten 5 dk suruyor en fazla 10 dk ya dusurmem lazim    bir oneriniz olurmu.Whre kosulu olmadgindan onceki soruyu oyle sordum.

     

    SELECT

    f.DevID

    , FirstTime = CASE WHEN COUNT(distinct f.InsId ) = 1 THEN ‘YES’

    ELSE ‘NO’

    END  <

  •  Ayrica tablonuzda PersonelAdi ve IseGirisTarihi kolonlarindan baska kolonda varsa, bu iki kolona tek bir index atarsaniz, full table scan yerine full index scanla verilere ulasabilirsiniz. Buda tum kayitlarin daha hizli gelmesini saglayacaktir.

  • yazmak istediginiz sorgu tablodaki tum kayitlari getirecektir. bu durumda full table scan yapacagi için zaten index kullanmayacak. Fakat siz bir clustered index olusturursaniz, en azinda verilerin fiziksel olarakda diskde sirali kaydolmasini saglayarak performans artisi saglayabilirsiniz

  • verdiginiz ornek su >  Select PersonelAdi, IseGirisTarihi from Personel where PersonelID = 13 

    peki soyle olursa sorgumuz nasil index vermeyi tavsiye edersiniz  , en az usteki kadar performansli calisarak.

    Select PersonelAdi, IseGirisTarihi from Personel

     

    Where kosulu olmadan. 

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir