MSSQL Server Page Split Nedir

Bu makalede Page Split konusunu detaylı bir şekilde ele almış olacağız. SQL Server, verileri 8 KB’lık sayfalarda (pages) tutar. Bir tabloya veri eklediğinde ya da bir satır güncellendiğinde, bu veri bu sayfalar içinde yer bulur.

Page Split durumu şudur:

Veri eklemek istediğin sayfa doluysa ve yeni veriyi o sayfaya sığdıramıyorsa, SQL Server o sayfayı ikiye böler (split eder), verinin bir kısmını yeni oluşturduğu sayfaya taşır ve sonra veriyi ekler. Bu işleme Page Split denir.

Örneğin bir tablo düşün:

CREATE TABLE Customers (
   ID INT PRIMARY KEY,
   Name VARCHAR(50)
)

Bu tabloya sıralı şekilde ID’ye göre veri ekliyorsan, sayfalar arka arkaya dolar. Ama araya yeni bir kayıt eklersen (ID=3 gibi) ve ilgili sayfa dolmuşsa, SQL Server:

  1. Yeni bir sayfa (page) oluşturur.
  2. Mevcut sayfadaki bazı verileri yeni sayfaya taşır.
  3. İstediğin veriyi araya ekler.
  4. Bu işlem sırasında hem ek işlem maliyeti, hem de geçici kilitlenmeler olur.

Page split’ler performansı negatif etkiler: Fazladan CPU ve IO kullanımı olur. Fragmentation (parçalanma) artar → sorgular yavaşlar.

WITH (NOLOCK) kullanan bir sorgu tam o sırada okuma yaparsa: Verinin bir kısmını eski sayfadan, bir kısmını yeni sayfadan okur, Bu da eksik veya iki kere okuma (double read) gibi hatalara yol açabilir.

Bu işlem nasıl azaltılır:

  • Sıralı veri eklemeye çalış. (Clustered Index sırasına uygun)
  • Fill factor ayarını düşür. (örneğin %90 yerine %80 bırak, boş yer kalsın)
  • Index bakımını düzenli yap (reorganize / rebuild)

REORGANIZE işlemi page split sayacını sıfırlamaz. Page split (sayfa bölünmesi), bir veri sayfası dolduğunda ve yeni veri eklendiğinde, SQL Server’ın bu sayfayı ikiye bölmesiyle oluşur. Bu, genellikle verinin ortasına yapılan eklemelerde olur (özellikle sıralı olmayan insert’lerde). page split sayacı bu işlemden etkilenmez. Bu sayaç, özellikle DMV’lerde (sys.dm_db_index_operational_stats) takip edilir. REORGANIZE, yalnızca mevcut sayfalardaki verileri yeniden düzenler, yani daha verimli bir sıraya sokar.

Index rebuild işlemlerinde ise REBUILD, indeksi tamamen yeni baştan oluşturur. Bu nedenle: Fragmentation tamamen temizlenir. Tüm sayfalar yeni baştan yapılandırılır. Page split sayacı sıfırlanır.

Page split’ler çoğunlukla leaf-level page’lerde yaşanır.

Page Split olayını daha detaylı bir şekilde ele alalım. Bir sayfa (page) dolduğunda ve yeni veri oraya sığmayacak kadar büyükse, SQL Server ne yapar?

Diyelim ki elimizde şöyle bir yapı var:

  • Clustered Index var → veriler sıralı tutuluyor (örneğin ID’ye göre).
  • Sayfa dolmuş (8 KB kapasite tamamlanmış).
  • Yeni bir satır, mevcut sıralamaya göre araya eklenmek isteniyor (örneğin ID=5 ekleniyor ama sayfa 1–10 arası dolu).

SQL Server aşağıdaki adımları izler:

  1. Yeni bir veri sayfası oluşturur (aynı extent içinde olabilir, farklı da olabilir).
  2. Mevcut sayfadaki verilerin yaklaşık yarısını alır ve bu yeni sayfaya taşır.
  3. Yeni veriyi, sıralamaya uygun şekilde eski sayfaya mı yoksa yeni sayfaya mı denk geliyorsa oraya ekler.
  4. Index pointer’larını (yani üst seviye B-Tree bağlantılarını) günceller.
  5. Eski ve yeni sayfalar artık veriyi paylaşıyor ve sıralı yapıyı koruyor.

Örneğin elimizde bir page’de şu satırlar var. (ID’ye göre sıralı):

[1] [2] [3] [4] [5] [6] [7] [8]
  • Bu sayfa dolu ve sıralı.
  • Şimdi ID = 4.5 eklemek istiyoruz.

Page Split Olur:

  • SQL Server yeni sayfa açar.
  • Diyelim şu şekilde böldü:
Page 1 → [1] [2] [3] [4]
Page 2 → [5] [6] [7] [8]
  • Yeni kayıt (4.5) sıralamaya göre Page 2‘ye eklenir:
Page 2 → [4.5] [5] [6] [7] [8]

Böylece sıralama korunur ama performans düşer, çünkü:

  • Veri taşındı
  • Yeni sayfa yazıldı
  • Index güncellendi

Page split sadece INSERT’te olmaz. UPDATE ile satır uzarsa ve mevcut sayfada yer yoksa, aynı şey olabilir. Yani “sadece veri eklerken” değil, güncellerken de page split yaşanabilir.

Aşağıdaki komut ile page split sayısını dolaylı olarak bulunabilir.

SELECT 
    OBJECT_NAME(ios.object_id) AS TableName,
    i.name AS IndexName,
    ios.index_id,
    ios.leaf_insert_count,
    ios.leaf_delete_count,
    ios.leaf_update_count,
    ios.range_scan_count,
    ios.singleton_lookup_count
FROM sys.dm_db_index_operational_stats (DB_ID(), NULL, NULL, NULL) AS ios
JOIN sys.indexes AS i
    ON ios.object_id = i.object_id AND ios.index_id = i.index_id
WHERE OBJECTPROPERTY(ios.object_id, 'IsUserTable') = 1;

leaf_insert_count sayısı ile page split sayısını tahmin edebiliriz.

DurumAçıklama
Page split olduğundaEn az 1 yeni 8 KB page tahsis edilir
Yeni page hangi extente gider?SQL Server, mevcut extent doluysa, yeni extent alabilir
Veriler taşınırEski sayfadan bazı satırlar yeni sayfaya taşınır
Index yapısı güncellenirB-tree yapısındaki pointer’lar, yeni page’i gösterecek şekilde güncellenir

Page split hem clustered hem de non-clustered index’lerde olabilir.

Page split’te neden sadece yarısı yeni page’e taşınır. SQL Server veri sırasını korumak zorundadır (özellikle clustered index varsa). Bu yüzden veri eklemesi yapılacak sayfa dolduğunda, veriyi düzgün şekilde dağıtmak için mevcut verinin yaklaşık yarısını yeni sayfaya taşır.

Heap’lerde sıralama olmadığı için “page split” teknik anlamda olmaz. Ancak, eğer bir row update sonucu satır artık mevcut page’e sığmazsa: → SQL Server bu satırı başka bir page’e taşır ve eski yerine bir “forwarding pointer” bırakır. → Bu da performansı düşürür ama “page split” sayılmaz.

Yapı TürüPage Split Olur mu?Açıklama
Clustered Index✅ EvetSıralı veri yapısı, araya ekleme zorunluluğu var
Non-Clustered Index✅ EvetAynı şekilde sıralı yapı var
Heap (indexsiz tablo)❌ (ama benzeri etki olur)Forwarded row oluşabilir, ama “split” değildir

Page Split ve Boşluk Yönetimi

1. Page Boşluğu Yönetimi:

  • SQL Server, her sayfayı 8 KB’lık küçük parçalara ayırır.
  • Boşluk (internal fragmentation) olduğu sürece, yeni eklenen veri bu boş alanlara yazılmaya çalışılır. İlk başta boş yer herhangi bir page üzerinde doldurulur.
  • Bu sayfalar fiziksel olarak doldukça, boş yer kalmaz.

Örnek:

  • Diyelim ki 10 numaralı page boş ve eklemeye yeni veriler gelecek.
  • İlk başta boş alanlar bu page üzerinde doldurulur.

2. Page Dolduğunda:

  • 10 numaralı page tamamen dolarsa ve ekleme yapılacak yer kalmazsa, SQL Server yeni bir page oluşturur (örneğin 350. page).

3. Page Split İşlemi:

  • Sayfa dolduktan sonra, yeni veri eklenemediği için page split işlemi gerçekleşir.
  • Sayfanın yaklaşık yarısı yeni sayfaya (örneğin 350. page) taşınır. Bu taşıma, genellikle sayfanın ortasında yapılır (ama bazen sayfanın tam ortasında değil, verinin sıralamasına göre).

4. Page Split ve Sıralama:

  • Veriler sıralı kalır. Yani, eski sayfanın yarısı taşındığı yeni sayfada veriler yine sıralı olur.

Sonuç:

  • Bu durumda, 10 numaralı page’den taşınan veriler 350 numaralı page’e eklenir ve sıralama korunur.
  • Bu taşıma mantıksal sıralamayı etkilemez, ancak fiziksel yerleşimi bozar. Bu da logical fragmentation anlamına gelir.

Özetle:

  • Sayfa dolduğunda, boşluk varsa ilk başta o boşluğu doldurur.
  • Eğer veri 10 numaralı sayfaya eklenmesi gerekiyorsa ama yer yoksa:
    • Page Split yapılır.
    • Verinin bir kısmı, örneğin 350 numaralı sayfa’ya taşınır.
  • Bu taşınan veriler sıralı olur, ancak fiziksel yerleşim bozulur. Bu da logical fragmentation yaratır.

SQL Server’da iki tür fragmentation vardır:

TürAçıklama
Logical Fragmentation (External)Index sırasına göre ardışık olan verilerin fiziksel olarak ardışık page’lerde olmaması durumu.
Internal FragmentationBir sayfanın içinde boşluk kalması (%100 dolu olmaması) — örn. %50 dolu sayfalar.

Bir programın 10.5 KB belleğe ihtiyacı var: Kalan 1.5 KB boşa gider → internal fragmentation

Kısacası:

  • Internal fragmentation, sayfa içinde boş kalan kullanılmayan alanlardır.
  • Sıralama bozukluğu değil, boşluk israfı ile ilgilidir.
  • Sayfa sırasının bozulması değil, alanın tam kullanılamaması söz konusudur.

Bu makalede page split konusunu detaylı bir şekilde görmüş olduk. Başka bir makalede görüşmek dileğiyle..

“Helâlinden kazanmak hak yolunda yapılan muhârebe kadar ecirlidir.”

Author: Yunus YÜCEL

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir