|
INDEX FRAGMENTATION
Bildiğimiz üzere index’ler bilgisayarda
B-Tree yapısında tutulmaktadır.Bir kayıt ekleneceği zaman veya güncelleneceği zaman
eğer sayfalarda dolma meydana geliyorsa sayfa ikiye bölünecek ve B-Tree yapısı değişecektir.(Page
Splitting).Dolayısıyla bölünmeden önce birarada bulunan key’ler bölünme sonrasında
farklı yerlerde bulunmaları gerekecek.
Sırasıyla 5,10,15,20 değerlerinin
bulunduğu ve 4 değer kabul eden bir page(index page) olduğunu düşünün.Yani her biri
integer olan 4 değer,yani 4*4 =16 byte’lık index page’lerimizin olduğunu düşünün.Bu
durumdayken 17 değerinin index page’ler içerisinde yer almak istediğini farzedelim.Bu
sayfaya sığmayacak.Bu durumda bu sayfa ikiye bölünecek 5 ve 10 bir başka sayfada,15
ve 20 bir başka sayfada,17 ise diğer bir başka sayfada yer alacak.5-10 ve 15-20
çiftleri artık mantıksal olarak çizebileceğimiz B-Tree yapısında farklı yerdeler
ve aynı gruptalar.Fakat bu değerler zamanında harddisk üzerinde yanyana yazılmışlardı.Velhasıl
kelam son durumda bu 4 tane key,harddiskte yanyana dururken,mantıksal olarak farklı
farklı yerlerde durmaktadırlar.Sürekli ekleme silme yapılan bir index yapısında
da,mantıksal olarak yanyana olması gereken bir sürü key aslında harddisk üzerinde(fiziksel
ortamda) farklı farklı yerlerde durmaktadırlar.Bir veri okunacağı zamanda harddiskin
kafası ordan buraya savrulacaktır.Tabi harddisk kafasının(head) bir oraya bir buraya
mantığıyla hareketi performansı düşürecektir.İşte page’lerin mantıksal olarak yanyana
olması fakat gerçekte yani harddisk üzerinde yani fiziksel olarak ayrı ayrı yerlerde
durması olayına external fragmentation
denilmektedir.
Diğer bir fragmentation ise internal
fragmentation’dır.Onun açıklaması şöyledir.Farzedinki bir index page içerisinde
5,10,15,20 değerleri var.Daha sonra bu değerlerden 10,15 ve 20 silindi.4 koltukluk
yerde şu an sadece bir adet key oturmaktadır.Bu olayın başka başka page’lerde de
olduğunu düşünürsek,ortalarda çoğu veya bir kısmı boş olan bir sürü sayfa olacaktır.her
ne kadar yeni gelecek olan key’ler için oturacak boş koltuk sayısı fazla olsada,harddisk
üzerinde bu sayfaların belleğe yükleme işlemi sırasında n tane sayfa yüklemesi,elimizdeki
index key’leri yeterli iken biz n+x adet sayfayı belleğe yükleyeceğiz.Yine harddisk
kafasının çok fazla sayfa gezmesi,ordan oraya savrulması performansı olumsuz etkilecektir.İşte
sayfalar içerisinde böyle boşlukların kalması ve gerekenden fazla yerin zapdedilmesi
olayınada internal fragmentation denilmektedir.
Veri tabanınızda indexlerin berbat
durumda olup olmadığını,external veya internal fragmentation gerçekleşip gerçekleşmediğini
anlamak istiyor iseniz aşağıdaki karışık T-SQL komutunu çalıştırmanız gerekiyor.
|
SELECT OBJECT_NAME(dt.object_id), si.name,
dt.avg_fragmentation_in_percent, dt.avg_page_space_used_in_percent
FROM
(SELECT
object_id, index_id,
avg_fragmentation_in_percent, avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats (DB_ID('AdventureWorks'),
NULL, NULL, NULL,'DETAILED')
WHERE index_id <>
0) as dt --does not return information about heaps
INNER JOIN
sys.indexes si
ON si.object_id = dt.object_id
AND si.index_id
= dt.index_id
|
Bunun sonucunda şu şekilde kayıtlar
gelecektir.(Tabi AdventureWorks veri tabanında çalıştığımızı unutmayalım)
Bu tabloya bakarak şu yorumları
yapabiliriz;
·
Eğer avg_fragmentation_in_percent değeri 10’un üstündeyse o index için external
fragmentation vardır denir.
·
Eğer avg_page_space_used_in_percent değeri 75’in altında ise bu durumda da internal
fragmentation vardır denir.
Tabloya bakarak AdventureWorks veri
tabanının indexlerinin halinin pekde içaçıcı olmadığı söylenebilir.
ALTER INDEX ..REORGANIZE
REORGANIZE komutu ile dağınık yerlerde
duran,sayfalar üzerinde boş duran alanlar düzenlenir. Mantıksal olarak yanyana olan
değerler fiziksel olarak yanyana getirilir.Dolayısıyla bazen boş sayfalar oluşacaktır.Bu
sayfalarda sisteme verilerek yerden kazanç sağlanır.Belleğe yüklenecek sayfa sayısı
azaltılır ve mantıksal olarak birleşik olan fakat fiziksel olarak ayrı yerlerde
duran key’ler aynı sayfada soldan sağa sıralı olacak şekilde sıralanır.
Bir Index üzerinde bu işlemi yapmak
için şu T-SQL komutu kullanılır;
|
ALTER INDEX
PK_Employee_EmployeeID ON HumanResources.Employee
REORGANIZE;
|
ALTER INDEX ..REBUILD
REBUILD komutuyla birlikte index
adına ne var ne yok yok edilir.Dolayısıla ortada ne internal ne de external fragmentation
kalacaktır.Sonrada başla tekrardan index’leri düzenli bir şekilde oluşturmaya.Biraz
uzun bir iştir.Bu işi yapmak için gerekli T-SQL komutu ise şöyledir;
|
ALTER INDEX
PK_Employee_EmployeeID ON HumanResources.Employee
REBUILD;
|
Fragmentation’ların durumları çok
feci değil ise REORGANIZE,feci ise REBUILD seçeneğini seçmeliyiz.Bu feci kavramının
bir sınırı var mıdır? Microsoft’a göre şudur;
·
60< avg_page_space_used_in_percent <75 veya 10< avg_fragmentation_in_percent
<15 ise durum feci değildir ve REORGANIZE işimizi görür.
·
avg_page_space_used_in_percent <60 veya avg_fragmentation_in_percent > 15
ise durum fecidir ve REBUILD yapılmalıdır.
ÖRNEK: Employee tablosu için indexlerde REBUILD yapalım;
|
ALTER INDEX
ALL ON HumanResources.Employee
REBUILD WITH
(FILLFACTOR = 90,
ONLINE = ON);
|
Bu örnekte FILLFACTOR 90 olarak
belirlenmiştir.Bu şu demektir,Employee tablosu üzerinde bulunan bütün indexlemede
sayfaların %10’u boş kalacaktır gerisi doldurulacaktır.%10 boş bırakılmasının sebebi
yeni gelecek index keyleri için boş koltuk bırakmaış olmaktır.
ONLINE durumunun ON olması ise şu
demektir;Madem ki rebuild edilirken index’ler drop ediliyor bu durumda şöyle kullanıcı
madur kalabilir.İşte bunu engellemek adına ONLINE değeri ON yapılıyor,sorgu boyunca
index’ler işlemeye devam ediyor.
ÖRNEK: Employee tablosu için indexlerde REORGANIZE yapalım;
|
ALTER INDEX
PK_Employee_EmployeeID ON HumanResources.Employee
REORGANIZE;
|
Bu komutları çalıştırmadan önce
yukarıda bahsettiğim T-SQL komutuyla birlikte fragmentationların önce ve sonra hallerini
gözlemleyebilirsiniz.
|