3. Clustered İndeks Mimarisi
SQL Server’da, indeksler B tree içinde düzenlenirler. B treedeki indeks içindeki her page index node olarak adlandırılır. B-treenin en tepedeki nodu root node olarak adlandırılır. İndeksin en alt seviyesindeki nodlar leaf node olarak adlandırılır. Root ve leaf nodlar arasındaki herhangi bir indeks seviyesi ortak olarak intermediate seviyededir. Clustered indekste leaf nodelar tablo altındaki data pageleri içerirler. Root ve ara seviyedeki nodlar indeks satırlarını tutan indeks pageleri içerirler. Her indeks satırı bir anahtar değeri ve ara seviye sayfa göstergesi veya leaf level data row göstergesi içerir. Her seviye içindeki pageler doubly-linked list içinde bağlıdırlar.
Veri zincirindeki pageler ve onun içindeki satırlar clustered indeks anahtar değerine göre sıralanır. Tüm INSERT işlemleri, diğer satırların arasında anahtar değerine uygun satıra yapılır. B-tree için page collectionlar, sys.system_internals_allocation_units’ deki page pointerlar tarafından bağlıdır.
Clustered indeks için, sys.system_internals_allocation_units içindeki root_page kolonu clustered indeksin en tepesini gösterir. Server dizideki anahtar değerine uyan satırı bulmak için indeksi bir alt satıra indirir. Anahtar sırasını bulmak için, SQL Server indeksi sırada hareket ettirir ve başlangıç anahtar değerini bulur ve sonra previous veya next pointerları kullanarak data pageleri tarar. Data page zincirindeki ilk sayfayı bulmak için, indeksin root nodundan en soldaki pointerları takip eder.
Şekil 1’ teki partitiondaki clustered indeks yapısını gösteriyor.
SQL Server’ın clustered indeksi nasıl oluşturduğunu görmek için bir tablo yaratıp kayıt girişi yapalım.
Create Table EmpTable2
( EmpId Int,
EmpName Varchar(8000) )
Insert Into EmpTable2 Values (4, Replicate ('d',2000))
GO
Insert Into EmpTable2 Values (6, Replicate ('f',2000))
GO
Insert Into EmpTable2 Values (1, Replicate ('a',2000))
GO
Insert Into EmpTable2 Values (3, Replicate ('c',2000))
GO
Sonuca göre kayıtlar yine giriş yaptığımız sıra ile görüntülüyor. DBCC Ind komutuyla page yapısına bakalım:
DBCC TRACEON (3604)
GO
Declare @DBID Int, @TableID Int
Select @DBID = db_id(), @TableID = object_id('EmpTable2')
DBCC ind(@DBID, @TableID, -1)
Aslında yukarıdaki sorgulardan daha fazla kolon dönüyor ancak biz üç kolonu inceleyeceğiz.
PagePID: Fiziksel sayfa numarasıdır. Bizim yarattığımız koşullarda veriyi saklayan üç page bulunuyor.
IndexID: İndeks tipini gösterir.
0 – DataPage
1 - Clustered Index
2 - Veya daha büyükse Index page (Non-Clustered Index ve ordinary index)
PageType: Hangi türde veri sakladığını belirtir.
10 - IAM (Index Allocation MAP)
1 – DataPage
2 - Index Page
Şimdi de EmpId kolonuna Unique Clustered Index oluşturarak page yapılarına nasıl etki ettiğini inceleyelim:
CREATE UNIQUE CLUSTERED INDEX EmpTable2_EmpIndex
ON EmpTable2 (EmpID)
GO
Select EmpID From EmpTable2
Şimdi DBCC Ind (dbid, tabid, -1) komutunu çalıştırıp sonuca bakalım:
DBCC TRACEON (3604)
GO
Declare @DBID Int, @TableID Int
Select @DBID = db_id(), @TableID = object_id('EmpTable2')
DBCC ind(@DBID, @TableID, -1)
MSSQL, indeks için “page allocation details“ bilgisi içeren page (pagetype = 10) yaratır.
Şimdi 78 ve 118 numaralı pageleri inceleyelim:
DBCC TRACEON (3604)
GO
DBCC page(12, 1, 78, 3)
GO
Sonuç :
Record Type = PRIMARY_RECORD
EmpId = 1
mpName = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…….
Record Type = PRIMARY_RECORD
EmpId = 3
EmpName = ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccc…….
Yukarıdaki sonuca göre biz kayıtları sırasız bir şekilde eklememize rağmen, datapage’de kayıtlar sıralı bir şekilde gösteriliyor. Bir tabloya clustered indeks oluşurulursa datapagelerde fiziksel sıralama yapılır, indeks kolon baz alınarak fiziksel olarak sıralanır.
Şimdi tabloya bazı kayıtlar daha ekleyelim:
INSERT INTO EmpTable2 VALUES (10, Replicate ('j',4000))
INSERT INTO EmpTable2 VALUES (2, Replicate ('b',4000))
INSERT INTO EmpTable2 VALUES (5, Replicate ('e',4000))
INSERT INTO EmpTable2 VALUES (8, Replicate ('h',4000))
INSERT INTO EmpTable2 VALUES (9, Replicate ('i',4000))
INSERT INTO EmpTable2 VALUES (7, Replicate ('g',4000))
DBCC TRACEON (3604)
GO
Declare @DBID Int, @TableID Int
Select @DBID = db_id(), @TableID = object_id('EmpTable2')
DBCC ind(@DBID, @TableID, -1)
Yukarıdaki tabloda gösterilen, page allocation detayını içeren page detayına bakalım:
DBCC TRACEON (3604)
GO
dbcc page(12, 1, 80, 3)
GO
Sonuç:
IAM: Single Page Allocations @0x6212C08E
Slot 0 = (1:78)
Slot 1 = (1:89)
Slot 2 = (1:118)
Slot 3 = (1:120)
Slot 4 = (1:174)
Slot 5 = (1:45)
Slot 6 = (1:79)
Slot 7 = (1:94)
Şimdi indeks kaydına bakalım :
DBCC TRACEON (3604)
GO
dbcc page(12, 1, 118, 3)
Clustered Index kullanımı WHERE cümlesinde BETWEEN kullanıldığı zaman, verinin sıralanırken ve çok sayıda kayıt alınırken çok kullanışlıdır. Çünkü clustered indeksin leaf seviyesi veridir. Bu da çok sayıda I/O kaydetmek için kullanılacaktır. Yani clustered indeks kullanımı veri sıralama sorgularında en iyi çözümdür.
Referanslar
1. http://msdn.microsoft.com
Serap PARLAK
Yorumlar
Yorum Gönder