Ana içeriğe atla

Heap, Clustered İndeks ve Nonclustered İndeks Data Yapıları - Bölüm 3 (Nonclustered İndeks Mimarisi)


4. Nonclustered İndeks Mimarisi

Nonclustered indeks aşağıdaki farklılıklar dışında B-tree yapısını clustered indeks gibi kullanır:
  • · Tablodaki data satırları, nonclustered anahtarlarına göre sıralanıp depolanmaz.
  • · Nonclustered indeksin leaf katmanı data page yerine indeks pagelerle düzenlenir.
Nonclustered indeksler tablo veya view üzerine heap veya clustered indekslerle tanımlanabilirler. Nonclustered indekste her indeks satırı, nonclustered indeks key value ve bir row locator bulundurur. Bu yer bulucu, clustered indeks veya heapteki anahtar değerine sahip satırı işaret eder.
Nonclustered indeksteki satır bulucu, ya bir satır göstergesidir ya da satırın clustered indeks anahtarıdır. Buna göre:
  1. Tablo clustered indeks içermeyen bir heap ise; row locator bir satırı işaret eder. Bu pointer, dosya tanıtıcı (ID), sayfa numarası ve page üzerindeki satırların numaralarından oluşur. Bütün olarak bu pointer Row ID (RID) olarak tanımlanır.
  2. Eğer tablo bir clustered indekse sahipse veya indeksli bir view ise; row locator satırın clustered indeks anahtarıdır. Eğer clustered indeks unique indeks değilse, SQL Server, uniqueifier denilen kendisinin ürettiği değerleri ekleyerek duplicate keyleri unique yapar. Bu dört byte veri kullanıcıya gösterilmez. Bu sadece nonclustered indekslerde clustered anahtarlarını kullanması gerektiği zaman eklenir. SQL Server data satırını, nonclustered indeksin leaf satırlarında saklanan clustered indeks anahtarlarını kullanıp clustered indeksi arayarak elde eder.
Şekil 1:
Non-Clustered_Index_1-UNIVERA

Included Column Indexes

Nonclustered indeksin işlevselliği, indeksin leaf seviyesine nonkey kolon denilen included kolonlar eklenerek genişletilebilmesidir. Key kolonlar indeksin her seviyesinde saklanabilirken, nonkey kolonlar sadece leaf seviyesinde saklanabilirler.
SQL Server’ın nonclustered indeksi nasıl oluşturduğunu görmek için bir tablo yaratıp kayıt girişi yapalım.
Örnek Sorgular : Örnekler\1.Ornek3.sql
 
Create Table EmpTable1
(  EmpId Int,
   EmpName Varchar(8000)      )
Tablolar ilk yaratıldıklarında ön değer olarak yaratılan bir indeks yoktur. Teknik olarak indeks içermeyen tablolar ‘Heap’ olarak adlandırılır. Oluşturduğumuz tablonun indeks içermediğini sysindexes sistem tablosundaki “Indid” kolon değerinin 0 olup olmadığını sorgulayarak emin olabiliriz. Sysindexes table her vertiabanında bulunan tablo track’lerini ve indeks bilgilerini içeren bir tablodur. Bu tablodaki “Indid” kolonu index kimliğini belirtir ve Indid = 0 tablonun indeks içermediğini yani “heap” olarak saklandığını gösterir.
Tabloya bazı kayıtlar ekleyip sonuçlarına bakalım:
 
Insert Into EmpTable1 Values (4, Replicate ('d',2000))
Insert Into EmpTable1 Values (6, Replicate ('f',2000))
Insert Into EmpTable1 Values (1, Replicate ('a',2000))
Insert Into EmpTable1 Values (3, Replicate ('c',2000))
Select EmpID From EmpTable1
Non-Clustered_Index_2-UNIVERA
Sonuçta görüldüğü gibi kayıtlar giriş yaptığımız sıra ile görüntüleniyor.
Şimdi bazı komutlarla tablomuzun page bilgilerini inceleyelim:
 
DBCC TRACEON (3604)
GO
Declare @DBID Int, @TableID Int
Select @DBID = db_id(), @TableID = object_id('EmpTable1')
DBCC ind(@DBID, @TableID, -1)
Non-Clustered_Index_3-UNIVERA
Şimdi DBCC PAGE komutuyla data pageleri inceleyelim.
DBCC page(dbid, fileno, pageno, option)
Dbid: Veritabanı ID
FileNo: Page in file numarası. Birden fazla dosya ile çalışmıyorsak 1 olacaktır.
Pageno: DBCC IND ile alacağımız page numarası
Option: 0, 1, 2, 3 olabilir.
 
DBCC TRACEON (3604)
GO
Declare @DBID Int
Select @DBID = db_id()
DBCC page(@DBID, 1, 73, 3)
Yukarıdaki sorgu ile 73 numaralı page içerisindeki dataya ulaşabilirim. Bu sonuç MSSQL’in verilerle kolon adlarının datapage içerisinde nasıl bulunduğunu gösterir.
Sonuç:
Record Type = PRIMARY_RECORD
EmpId = 4
EmpName = ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
İncelediğimiz sonuçlar indeks içermeyen tablonun SQL içerisinde nasıl depolandığını gösteriyor. Şimdi bu tabloya Empid kolonuna unique non-clustered yaratarak veriye nasıl etki ettiğine ve nasıl depolandığına bakacağız.
 
CREATE UNIQUE NONCLUSTERED INDEX EmpTable1_empid
ON EmpTable1(EmpId)
Non-Clustered index oluşturulduktan sonra, DBCC Ind ile tekrar bakıyoruz sonuca
 
DBCC TRACEON (3604)
GO
Declare @DBID Int, @TableID Int
Select @DBID = db_id(), @TableID = object_id('EmpTable1')3
DBCC ind(@DBID, @TableID, -1)
Non-Clustered_Index_4-UNIVERA
Elde ettiğimiz sonuç indeks page detaylarını da içeriyor. Yeni alanlara bakarsak; page 89 indeks page için tahsis edilmiş page detayını gösterir, page 89 da indeks page detayını gösterir.
MSSQL indeks page için bir page (PageType=10) yaratır ve indeksin kullandığı page numarasını gösterir.
 
DBCC TRACEON (3604)
GO
Declare @DBID Int
Select @DBID = db_id()
DBCC page(@DBID, 1, 89, 3)
Sonuç:
IAM: Single Page Allocations @0x61D7C08E
Slot 0 = (1:80)
 
DBCC TRACEON (3604)
GO
Declare @DBID Int
Select @DBID = db_id()
DBCC page(@DBID, 1, 80, 3)
Non-Clustered_Index_5_Heap_RID-UNIVERA
SQL indeks kolonu sıralayarak yerleştirir. “HEAP RID” kolonu satır göstergesidir.
Satır göstergesi iki şekilde görüntülenir:
1. Tabloda clustered indeks varsa, satır göstergesi clustered indeks anahtar değeridir.
Bir tablodan tek satır döndürmek için Non-clustered indeks daha kullanışlıdır.
Örneğin; EmpId kolonuna non-clustered indeks yaratılmış tablodan EmpId vererek sorgu çektiğimizde EmpId ile eşleşen doğru sayfa ve satırdaki girişi bulmak için indekse bakar ve doğrudan bu page ve rowa gider. Bu da kayıt sorgulamayı oldukça hızlandırır.
Şimdi tablomuza satır ekleyelim clustered indeks ile non-clustered indeks yapısına bakalım. Kayıt ekledikten sonraki tablo görüntüsü aşağıdaki gibi olsun:
 
INSERT INTO EmpTable VALUES (10, Replicate ('j',4000))
INSERT INTO EmpTable VALUES (2, Replicate ('b',4000))
INSERT INTO EmpTable VALUES (5, Replicate ('e',4000))
INSERT INTO EmpTable VALUES (8, Replicate ('h',4000))
INSERT INTO EmpTable VALUES (9, Replicate ('i',4000))
INSERT INTO EmpTable VALUES (7, Replicate ('g',4000))
Select EmpID From EmpTable1
Non-Clustered_Index_6-UNIVERA
Sonuçta görüldüğü gibi veri hala bizim giriş yaptığımız sırada. Çünkü non-clustered indeks eklemek verinin nasıl saklandığını değiştirmez veri pagelerde sıralama yapar.
Şimdi DBCC Ind komutuyla yeni satırların nasıl eklendiğine bakalım:
 
DBCC TRACEON (3604)
GO
Declare @DBID Int, @TableID Int
Select @DBID = db_id(), @TableID = object_id('EmpTable1')
DBCC ind(@DBID, @TableID, -1)
GO
Non-Clustered_Index_7-UNIVERA
· Metot 1:
DBCC TRACEON (3604)
GO
Declare @DBID Int
Select @DBID = db_id()
DBCC page(@DBID, 1, 80, 3)
Non-Clustered_Index_8-UNIVERA
Yukarıdaki sonuçta görüldüğü gibi SQL Server’da indeks kolonun sıralanarak yerleştiriyor. “HEAP RID” kolonu satır göstergesini belirtiyor.
Satır göstergesinin iki tipi var demiştik. Yukarıdaki örnekte satır göstergesinin birinci metodunu görmüş olduk.
· Metot 2:
Şimdi de clustered ve non-clustered indeks içeren tabloda ikinci metodu inceleyelim. Öncelikle EmpTabl1 tablosuna bir kolon ekleyelim ve buna clustered indeks oluşturalım:
 
Alter Table EmpTable1 Add EmpIndex Int IDENTITY(1,1)
Kolon ekledikten sonra DBCC Ind komutuyla kontrol edersek de görebiliriz, kolon eklemek SQL Server tarafından ayrılan toplam page sayısını değiştirmez.
 
CREATE UNIQUE CLUSTERED INDEX EmpTable1_empindex
ON EmpTable1(EmpIndex)
Clustered Indeks eklendikten sonra page yapısı aşağıdaki gibi değişir:
 
DBCC TRACEON (3604)
GO
Declare @DBID Int, @TableID Int
Select @DBID = db_id(), @TableID = object_id('EmpTable1')
DBCC ind(@DBID, @TableID, -1)
Non-Clustered_Index_9-UNIVERA
90 ve 47 numaralı pageler page yerleşim detaylarını içerir. 73,110 ve 121 data page detaylarıdır.
Şimdi 90 ve 47 pagelerine bakalım:
 
DBCC TRACEON (3604)
GO
DBCC page(12, 1, 115, 3)
Non-Clustered_Index_10-UNIVERA
Yukarıdaki sonuç, veri page bağlantısı içeren(ChildPageId) clustered indeksi gösteriyor. EmpId kolonu, sayfada satır başlangıcını içeren indeks kolonudur.
 
DBCC TRACEON (3604)
GO
DBCC page(12, 1, 175, 3)
Non-Clustered_Index_11-UNIVERA
Yukarıdaki sonuç ile Metot 1 ve Metot 2 arasındaki farkı görebiliriz. Metot 1’de pageler satır göstergesini belirtirken Metot 2 deki clustered indeks anahtarlarını gösteriyor.
Metot 1 ve Metot 2 arasındaki en büyük fark datapagedeki satıra bağlanma şeklidir.
Referanslar

Serap PARLAK

Yorumlar

  1. Arkadaşlar ellerinize sağlık çok güzel bir çalışma teşekkürlerreplika telefonlar

    YanıtlaSil

Yorum Gönder

Bu blogdaki popüler yayınlar

UML ve Modelleme – Bölüm 4 (Class (Sınıf) Diyagramları)

Bir önceki makalemizde UML modellemede kullanılan ilk diyagram olan Use Case diyagramını incelemiştik. Bu makalemizde nesne tabanlı programlamada kullanılan sınıflar ve sınıfların arasındaki ilişkileri modelleyebileceğimiz diyagramlar olan Class(Sınıf) diyagramlarını inceleyeceğiz. UML’de sınıflar, nesne tabanlı programlama mantığı ile tasarlanmıştır. Sınıf diyagramının amacı bir model içerisinde sınıfların tasvir edilmesidir. Nesne tabanlı uygulamada, sınıfların kendi özellikleri (üye değişkenler), işlevleri (üye fonksiyonlar) ve diğer sınıflarla ilişkileri bulunmaktadır. UML’de sınıf diyagramlarının genel gösterimi aşağıdaki gibidir. Şekil 1. Class Diyagram Şekil1’de görüldüğü üzere bir dikdörtgeni 3 parçaya bölüyoruz. En üst bölüm sınıf adını, orta kısım özellik listesini (üye değişkenler) ve en son kısım, işlev listesini (üye fonksiyonlar) göstermektedir. Çoğu diyagramlarda alt iki bölüm çıkarılır. Genelde tüm özellik ve işlevler gösterilmemektedir. Ama

Yazılım Maliyet Tahmineleme Tecrübeleri

Yazılım mühendisliğinde maliyet hesabı her zaman problem olmuştur. "Bu iş kaç Adam/Gün tutar?" sorusuyla sıkça karşılaşıyoruz. Adam/gün veya Adam/ay ölçütleri bir kaynağın/kişinin belirtilen zaman dilimindeki iş gücü anlamına gelir. Tabi bu noktada yine kafa karışıklıkları başlar. 6 A/G'lik bir işi hızlandıralım diye 2 kişi ile yapmaya çalışsak ve kaynak/kod, modül, altyapı, insan vb. her bir şeyi bir kenara bıraksak, matematiksel basit formülle 6/2=3 A/G'de biter? Gerçek hayat böyle değil, öncelikle bunu anlamamız lazım. Hep şu örnek verilir; "Aynı bebeği 2 kadın birlikte daha kısa sürede doğurur mu?" Eğer bunun cevabı "Evet" ise (veya bir gün böyle bir durum ortaya çıkarsa), yazımı değiştirmem gerekecek:) Mevzu gerçekten derin...Maliyet hesabı; bulunduğunuz firmanın yazılım süreçlerini hangi methodlarla uyguladığına, ilgili işin o dönemdeki aciliyetine, (şirket yönetiminin baskısına:)) vb. bir çok duruma bağlı olabilir. Örneğin; bizim firmada e

UML ve Modelleme – Bölüm 3 (Use Case Diyagramlar)

Önceki iki makalemizde ( 1 , 2 ) UML’e genel olarak değinip ve modellemede kullanacağımız dokuz diyagram hakkında bilgiler vermiştik. Bu makalemizde Use Case diyagramından detaylı bahsedeceğiz. Öncelikle, genel Use case diyagramının tanımını hatırlayalım. “Bir kullanıcı ve bir sistem arasındaki etkileşimi anlatan senaryo topluluğudur.” Ivar Jacobson Senaryo tanımı için der ki: “Aktörle sistem arasında gerçekleştirilen, sonucunda aktöre farkedilir getirisi/ faydası oluşan etkileşimli diyalogdur. ” UML Use Case Diyagramları  sistemin işlevselliğini açıklamak amacıyla kullanılır. Sistemin birbirinden ayrı özelliklerinin detaylarını göstermekten ziyade, Use Case Diyagramlar, tüm mevcut işlevselliği göstermek için kullanılabilir. Buradaki en önemli noktalardan biri,   Use Case Diyagramlar temelde sequence diyagram ve akış diyagramlarından farklıdır. Use Case diyagramlar dört ana elemandan oluşmaktadır. Aktörler , Sistem (Proje kapsamını belirtir) , Use Caseler ve bunlar ara