kümelenmiş dizin üzerinde yeniden oluşturma, veri boyutu neden küçülür?


10

İçinde yaklaşık 15 gb veri bulunan bir tablodaki kümelenmiş bir dizinde yeniden oluşturma yaptığımızda ve veri boyutu 5 gb'a küçültüldüğünde, bu nasıl olabilir? Ne tür bir "veri" kaldırılır?

Veri boyutu i DBCC sp_spaceused "veri" sütunu anlamına gelir

Kümelenmiş dizinde yeniden oluşturmadan önce:

name                  rows        reserved    data        index_size  unused
LEDGERJOURNALTRANS    43583730    39169656 KB 15857960 KB 22916496 KB 395200 KB

Kümelenmiş dizinde Yeniden oluşturduktan sonra:

name                  rows        reserved    data        index_size  unused
LEDGERJOURNALTRANS    43583730    29076736 KB 5867048 KB  22880144 KB 329544 KB

Yeniden yapılandırma için TSQL:

USE [DAX5TEST]
GO
ALTER INDEX [I_212RECID] ON [dbo].[LEDGERJOURNALTRANS] REBUILD PARTITION = ALL WITH ( PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, ONLINE = ON, SORT_IN_TEMPDB = OFF, DATA_COMPRESSION = PAGE, FILLFACTOR = 85 )
GO

Veri boyutunu dosya boyutundan mı belirliyorsunuz?
JNK

Veri boyutu i DBCC sp_spaceused "veri" sütununu kastediyor
Daniel Björk

Bu, "veri" sütunu olacaktır EXEC sp_spaceused.
RLF

1
Her vücut OP onun yeniden oluşturma komut dosyası etkin = sayfa sıkıştırma kullanıyor kullanıyor ve daha önce değildi sanırım kaçırdı. Daniel onaylayabilir misin?
Shanky

1
@Shanky: Bu ALTER INDEXifade, kod tarafından oluşturulmuş gibi görünüyor (varsayılan ayarlarında bir grup seçenek içerdiğinden), bu yüzden dizinin mevcut seçeneklerinden oluşturulduğundan şüpheleniyorum. Ama haklısınız: sıkıştırma eğer değildi bu o kesinlikle veri ayak izi azalma en açıklıyor çalıştırıldı önce kümelenmiş endeksi sağladı. (tekrar: Daniel, şu ya da bu şekilde doğrulayabilir misiniz?)
David Spillett

Yanıtlar:


16

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 13ve 17bö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, FILLFACTORbir 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, FILLFACTORbu 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 INDEXYukarı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.


2
+1 Sayfa doldurma faktörü% 100'den düşükse, örneğin sayfa doldurma faktörü% 50 ise, yeni yeniden oluşturulmuş kümelenmiş dizin ( tablo )% 100 doldurma faktörü ile yeniden oluşturulduğundan iki kat daha büyük olur.
Max Vernon

6

Bir dizini yeniden oluşturduğunuzda, tüm verileri tam anlamıyla yeni sayfalara yerleştirir. Ne olduğundan şüphelendiğim gibi, yeniden oluşturma işleminden önce çok fazla veri kaldırdınız, örneğin bir sütunu kaldırdınız, daha az veri elde etmek için değişken genişlikli bir sütunu güncellediniz, sabit genişlikli bir sütun boyutunu değiştirdiniz veya çok sayıda satır sildiniz. Bu işlemlerin her ikisi de sayfalarda çok fazla boş alan bırakabilir ve bu, yeniden oluşturuluncaya kadar geri kazanılmaz. İçindeki "veri" sütunu sp_spaceusedgerçek verileri değil, verileri depolamak için kullanılan 8K sayfa sayısını ölçüyor. Bu sayfalar yeniden oluşturma nedeniyle artık daha dolu, bu nedenle aynı miktarda veri daha az sayıda sayfaya sığıyor.


5

sp_spaceusedSaklı yordam veritabanında toplam satır culmulative boyutu incelenmesi değildir. Verileri tutmak için ayrılan alanın boyutu, veriler için ayrılan uzantıların kümülatif boyutunda raporlanmaktadır.

Silinen birçok satır gibi önemli bir serbest alan varsa, kümelenmiş dizinin yeniden oluşturulması, sayfalardaki alanı sıkıştırır ve performans nedenleriyle daha verimli (yani daha küçük) olur.

Dolayısıyla, hiçbir veri atılmamalıydı, ancak yeniden oluşturma işlemi, veri sayfalarına yerleştirilen boş alanı tekrar kullanılabilir hale getirdi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.