Bir tablo kümelenmiş bir dizin varsa, dizin olan tablo verileri (aksi takdirde bir yığın tipi tablo var). Kümelenmiş dizinin yeniden oluşturulması (aslında herhangi bir dizin, ancak boşluk, kümelenmemiş bir dizin için "veri" olarak sayılmaz), kısmen kullanılan sayfaların daha tam bir biçimde birleştirilmesine neden olur.
Bir dizine veri ekledikçe (kümelenmiş veya başka şekilde) dizin sırası yaprak sayfaları gerektiği gibi oluşturulur ve yalnızca tek bir kısmi sayfanız olur: sonunda. Dizin sırasından veri girerken, verilerin doğru yere sığması için bir sayfanın bölünmesi gerekir: yaklaşık yarısı dolu iki sayfa elde edersiniz ve yeni satır bunlardan birine girer. Zamanla bu, çok fazla olabilir, makul miktarda ekstra alan tüketir, ancak gelecekteki eklemeler bir ölçüde boşlukları doldurur. Yaprak olmayan sayfalar da benzer bir etki görecektir, ancak gerçek veri sayfaları boyutlarından çok daha önemlidir.
Ayrıca silmeler kısmi sayfalarla sonuçlanabilir. Bir sayfadaki tüm satırları kaldırırsanız, "kullanılmayan" olarak sayılır, ancak bir veya daha fazla veri satırı kaldıysa hala kullanımda sayılır. Bir sayfada 10 bayt kullanan tek bir satır olsa bile, bu sayfa kullanılan alan sayımında 8192 bayt olarak sayılır. Yine gelecekteki uçlar boşluğun bir kısmını doldurabilir.
Değişken uzunluktaki satırlar için güncellemeler de aynı etkiye sahip olabilir: bir satır küçüldükten sonra sayfasında daha sonra yeniden kullanımı kolay olmayan bir alan bırakabilir ve neredeyse tam bir sayfadaki bir satır uzadığında sayfa bölünmesi zorlanabilir .
SQL Server, çöp toplama alıştırmaları bir performans kabusu olabileceğinden, dizin yeniden oluşturma siparişiniz gibi açıkça belirtilinceye kadar sayfaların nasıl kullanılacağını yeniden düzenleyerek verileri normalleştirmeye çalışırken zaman harcamaz.
Gördüğünüz şey olduğundan şüpheleniyorum, ancak verinin kesinlikle ihtiyaç duyduğu miktarın yaklaşık 2,7 katı için yeterli alana sahip olmanın özellikle kötü bir durum olduğunu söyleyebilirim. Dizindeki önemli anahtarlardan biri (belki de bir UUID sütunu) olarak rastgele bir şeye sahip olduğunuz anlamına gelebilir, bu da yeni satırların dizin sırasına eklenmesinin olası olmadığı ve / veya son zamanlarda önemli sayıda silme işleminin gerçekleştiği anlamına gelir.
Sayfa Bölme Örneği
Dörtü bir sayfaya sığacak şekilde sabit uzunluklu satırlarla dizin sırasına göre ekleme:
Start with one empty page:
[__|__|__|__]
Add the first item in index order:
[00|__|__|__]
Add the next three
[00|02|04|06]
Adding the next will result in a new page:
[00|02|04|06] [08|__|__|__]
And so on...
[00|02|04|06] [08|10|12|14] [16|18|__|__]
Şimdi dizin sırasından satır eklemek için (bu yüzden sadece yukarıdaki sayıları bile kullandım): Ekleme 11
, ya ikinci sayfayı genişletmek (sabit boyutta oldukları için mümkün değildir) anlamına gelir, 11'in üzerindeki her şeyi bir üste taşımak (çok pahalı) büyük bir dizin) veya sayfayı şu şekilde bölme:
[00|02|04|06] [08|10|11|__] [12|14|__|__] [16|18|__|__]
Buradan, şu anda ilgili sayfalarda yer olduğu için ekleme 13
ve 17
bölünmeye neden olmaz:
[00|02|04|06] [08|10|11|__] [12|13|14|__] [16|17|18|__]
ancak 03 eklendiğinde:
[00|02|03|__] [04|06|__|__] [08|10|11|__] [12|13|14|__] [16|17|18|__]
Gördüğünüz gibi, bu ekleme işlemlerinden sonra şu anda toplam 20 satıra sığabilecek 5 veri sayfamız var, ancak orada sadece 14 satır var (alanın% 30'unu "harcıyor").
Varsayılan seçeneklerle ("doldurma faktörü" hakkında aşağıya bakın) bir yeniden oluşturma aşağıdakilerle sonuçlanır:
[00|02|03|04] [06|08|10|11] [12|13|14|16] [17|18|__|__]
bu basit örnekte bir sayfa kaydetme. Silme işlemlerinin dizin dışı sıralı eklerle nasıl benzer bir etkiye sahip olabileceğini görmek kolaydır.
hafifletme
Verilerin dizin sırasına göre oldukça rastgele bir sırada gelmesini bekliyorsanız, FILLFACTOR
bir dizin oluştururken veya yeniden oluştururken bu seçeneği SQL Server'a daha sonra doldurmak için yapay olarak boşluk bırakmasını ve uzun vadede sayfa bölünmelerini azaltmasını söylemek için kullanabilirsiniz, ancak başlangıçta daha fazla yer kaplar. Tabii bu değeri yanlış yapmak, durumu daha iyi hale getirmek yerine işleri daha da kötüleştirebilir, bu yüzden dikkatli davranın.
Sayfa bölme, özellikle kümelenmiş dizin üzerinde, eklemeler / güncellemeler için bir performans etkisi olabilir, FILLFACTOR
bu nedenle bazen çok fazla yazma etkinliği gören veritabanlarında alan kullanımı sorunu yerine (ancak okumaların yazmalardan ağır bastığı çoğu uygulama için) birkaç büyüklükte, etkili bir şekilde rastgele içeriğe sahip sütunlar üzerinde dizinlerin olduğu gibi belirli durumlar dışında, dolgu faktörünü% 100'de bırakmanız daha iyidir).
Diğer büyük ad DB'lerinin de benzer bir seçeneğe sahip olduğunu varsayıyorum, eğer bu kontrol düzeyine de ihtiyacınız varsa.
Güncelleme
ALTER INDEX
Yukarıdakileri yazmaya başladıktan sonra soruya eklenen ifadeyle ilgili olarak : Seçeneklerin dizinin ilk oluşturulduğu (veya son yeniden oluşturulduğu) zamanla aynı olduğunu varsayıyorum, ancak değilse, bu eklendiğinde sıkıştırma seçeneği çok önemli olabilir zaman içinde. Ayrıca bu ifadede dolgu faktörü% 100 değil% 85 olarak ayarlanır, böylece her yaprak sayfası yeniden oluşturma işleminden hemen sonra ~% 15 boş kalır.