Veritabanı boyutu - MDF çok mu büyük?


10

Yaklaşık 2.9Tb veri (2 x 1.45Tb - bir RAW şeması ve ANALYSIS şeması var yani temelde yutulan verilerin iki kopyası) barındıran bir SQL Server 2005 veritabanı sürdürüyorum. Kurtarma modeli SIMPLE ve .ldf6Gb'de.

Hangi nedenle olursa olsun .mdf, 7.5Tb. Şimdi, ANALYSIS tablolarında sadece 2-3 ek sütun var ve çok fazla NVARCHAR(MAX)sütun yok, ki ben (yanlış anladığımdan - yanlışsam lütfen beni düzeltin) ek alan tahsisine neden olabilir. Bu, şimdi veritabanını daralttıktan sonra - bundan önce ~ 9Tb idi. Düşüncesi olan var mı?

Ve, başka sorularınız varsa lütfen bize bildirin - Veritabanı yönetimi ve optimizasyon çabalarında çok yeniyim (genellikle işin bu tarafını yapmıyorum :)).

Çok teşekkürler!

Andrija


Teşekkürler Marc - bu soruyu oraya taşıyabilir miyim yoksa yeniden göndermem gerekir mi?

Şerefe - muhtemelen tahmin edebileceğiniz gibi, ben burada

Yanıtlar:


11

Boyut tahminlerinizde, dizinlerin aldığı alan miktarını dikkate aldınız mı? Ayrıca, çok baytlı ( N[VAR]CHARyerine [VAR]CHAR) olarak ayarlanmış metin alanlarınız varsa ve girdi dosyaları UTF-8 veya karakter başına düz bir baytsa, depolama gereksinimlerinizi iki katına kadar yükseltir. Ayrıca, bir tabloda kümelenmiş bir anahtar / dizin varsa, bunun boyutu, her satır için kümelenmiş anahtar değerini içerdiğinden, tablodaki diğer tüm dizinleri etkilediğini unutmayın (bir tablonun bir NCHAR ( ) INT'nin yapacağınız anahtar ve kümelenmiş anahtarınız / dizininiz bu veri sayfalarında yalnızca satır başına fazladan 16 bayt kullanmazsınız, ayrıca bu tablodaki diğer tüm dizinlerde satır başına 16 bayt harcarsınız ) .

Ayrıca, DB motoru silindikten sonra ayrılan bir alan bıraktığından, bu tablodaki yeni veriler için tekrar hızlı bir şekilde kullanılabilmesi için veya ekleme ve silme kalıbının yalnızca birçok sayfa bırakması nedeniyle bir miktar alan ayrılır ancak kullanılmaz. tam.

Koşabilirsin:

SELECT o.name
     , SUM(ps.reserved_page_count)/128.0 AS ReservedMB
     , SUM(ps.used_page_count)/128.0 AS UsedMB
     , SUM(ps.reserved_page_count-ps.used_page_count)/128.0 AS DiffMB
FROM sys.objects o  
JOIN sys.dm_db_partition_stats ps ON o.object_id = ps.object_id  
WHERE OBJECTPROPERTYEX(o.object_id, 'IsMSShipped') = 0  
GROUP BY o.name  
ORDER BY SUM(ps.reserved_page_count) DESC

hangi tabloların yer kapladığına hızlı bir bakış.

Ayrıca EXEC sp_spaceusedbu DB içinde çalıştırmak iki sonuç kümesi döndürür. Birincisi, veri dosyaları için dosya sisteminde ayrılan toplam alanı ve bunun ne kadarının ayrılmamış olduğunu, ikincisi ise tahsis edilen alanın ne kadarının veri sayfaları, dizin sayfaları için kullanıldığını veya şu anda kullanılmamış olduğunu listeler.

sp_spaceused belirli bir nesne tarafından kullanılan alanı da döndürür, böylece analiz için bir tablo oluşturmak üzere bunu döngüye alabilirsiniz:

-- TEMP TABLES FOR ANALYSIS
CREATE TABLE #tTables (sName NVARCHAR(MAX), iRows BIGINT, iReservedKB BIGINT, iDataKB BIGINT, iIndexKB BIGINT, iUnusedKB BIGINT)
CREATE TABLE #tTmp (sName NVARCHAR(MAX), iRows BIGINT, sReservedKB NVARCHAR(MAX), sDataKB NVARCHAR(MAX), sIndexKB NVARCHAR(MAX), sUnusedKB NVARCHAR(MAX))
-- COLLECT SPACE USE PER TABLE
EXEC sp_msforeachtable 'INSERT #tTmp EXEC sp_spaceused [?];'
-- CONVERT NUMBER-AS-TEXT COLUMNS TO NUMBER TYPES FOR EASIER ANALYSIS
INSERT #tTables SELECT sName, iRows
                     , CAST(REPLACE(sReservedKB, ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sDataKB    , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sIndexKB   , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sUnusedKB  , ' KB', '') AS BIGINT) 
                FROM #tTmp
DROP TABLE #tTmp 
-- DO SOME ANALYSIS 
SELECT sName='TOTALS', iRows=SUM(iRows), iReservedKB=SUM(iReservedKB), iDataKB=SUM(iDataKB),  iIndexKB=SUM(iIndexKB), iUnusedKB=SUM(iUnusedKB) FROM #tTables ORDER BY sName
SELECT * FROM #tTables ORDER BY iReservedKB DESC
-- CLEAN UP
DROP TABLE #tTables

Yukarıdaki kod, tüm tablo boyutlarını tek bir listede ve toplamlar için tek bir satır çıkarır. Gerekirse Eğer (gibi çeşitli sistem görünümleri kullanabilirsiniz sys.objectsve sys.dm_db_partition_statsyukarıdaki ilk sorguda kullanılan bakınız http://technet.microsoft.com/en-us/library/ms177862.aspx gibi daha fazla ayrıntı almak için çok daha fazla detay için) her bir dizin tarafından kullanılan alan.


Bir veri dosyasında üç kullanılmayan alan sınıfı vardır:

  1. Hiçbir şeye tahsis edilmeyen (bu, ilk sonuç kümesinde sp_spaceusedhiçbir nesne belirtilmemiş olarak gösterilir)
  2. Bir nesneye tahsis edilen (ayrılmış) ancak şu anda kullanılmayan ( sp_spaceusedçıkıştaki "kullanılmayan" sayımda gösterilir) .
  3. Kısmen kullanılan sayfalarda kilitli olan (her şey tek sayfa yığınlarına ayrıldığı için kullanılacak gibi görünecektir, bir sayfa 8.192 bayt uzunluğundadır). Bunu tespit etmek / hesaplamak daha zordur. İki faktörün bir karışımı nedeniyle:
    • Sayfaları böl. Veri ekledi alır gibi sık sık bölümü boş sayfa (depolama motoru ile bitirmek olabilir hep normalleştirmek sayfa içerikleri, ama bu çok verimsiz olur) ve satırlar silinir sayfa içeriği otomatik tekrar olabilecekleri (paketlenmiş, ama ekstra değildir I / o yükü genellikle uzak değerinde o) den.
    • Depolama motoru bir satırı birden fazla sayfaya bölemez (bu, satır başına 8.192 bayt sınırının geldiği sayfa boyutu ile birlikte). Satırlarınız sabit büyüklükte ve her biri 1,100 bayt alırsa, o tabloya tahsis edilen her veri bloğunun en az 492 baytını "harcayacaksınız" (7 satır 7,700 bayt alır ve 8'inci sığmaz, böylece kalan baytlar kazanır ' t kullanılabilir). Satırlar ne kadar geniş olursa, o kadar kötü olabilir. Değişken uzunluktaki satırlara (tamamen sabit uzunluklu olanlardan çok daha yaygın olan) sahip tablolar / dizinler genellikle daha iyidir (ancak konuyu hesaplamak daha az kolaydır).
      Buradaki başka bir uyarı büyük nesnelerdir ( TEXTsütunlar,[N]VARCHAR(MAX) belirli bir boyutun üzerindeki değerler vb.) sayfa dışına yerleştirildiklerinde, başka bir yerde verilere bir işaretçi tutmak için ana satır verilerinde 8 bayt alır), böylece satır başına 8,192 bayt sınırını kırabilir.

tl; dr: Beklenen veritabanı boyutlarının tahmin edilmesi, başlangıçta varsayılması doğal olandan çok daha fazla olabilir.


David - Ayrıntılı yanıt için çok teşekkür ederim! Şu anda db'yi analiz ediyorum ve hem sizin hem de Kenneth'in yanıtları veritabanı boyutunu etkileyen faktörleri anlamamda çok yardımcı oldu. Her zaman verimlilikle ilgileniyorum (hem veri alımı hem de veri kullanımı söz konusu olduğunda) ve sağladığınız bilgiler çok değerli!
Andrija_Bgd

6

sp_spaceusedVeritabanınızda çalışmayı deneyin . Örnek olarak şunu döndürür:

reserved           data               index_size         unused
------------------ ------------------ ------------------ ------------------
6032 KB            2624 KB            1664 KB            1744 KB

Veritabanında çalıştırmak için sadece USEveritabanı çalıştırın sp_spaceused.

Hala kullanılmayan büyük bir alan gösteriyorsa, büzülmeyi tekrar deneyebilirsiniz. Bazen birden fazla deneme gerektirdiğini görüyorum. Ayrıca bazen ben bir bütün olarak veritabanı yerine tek tek dosyayı küçültmek için en iyi buluyorum. Ancak bulabileceğiniz şey 2.9Tb veri ve başka bir 4 + Tb indeksiniz var, bu durumda 7.5TB oldukça makul. Her tablonun alan (veri ve dizin) miktarı hakkında fikir edinmek istiyorsanız, sp_spaceusedtablo düzeyinde de çalışabilirsiniz . Aşağıdaki komutu kullanarak veritabanındaki tüm tablolarda çalıştırabilirsiniz:

EXEC sp_msforeachtable 'EXEC sp_spaceused [?];'

Her ne kadar adil uyarı sp_msforeachtable belgelenmemiş olsa da, desteklenmemektedir ve tabloları kaçırdığı bilinmektedir. Öte yandan, kendimde oldukça şanslıydım.

Tüm bunlar, beklenen büyümenize bağlı olarak veritabanınızın belirli bir boş alan yüzdesine sahip olması gerektiği söyleniyor. Temel olarak, 6 aydan birkaç yıl büyümeye kadar herhangi bir yere sahip olduğunuzdan emin olmak istersiniz. Ayrıca autogrowthdurumunuza uygun olduklarından emin olmak için ayarlarınızı kontrol etmek isteyeceksiniz . Özellikle veritabanınızın boyutu göz önüne alındığında% kullanmak istemezsiniz autogrowth.


Teşekkür ederim! Sp_spaceused kullandım ve gerçek veriler aslında belirtilen miktarda yer kaplıyor gibi görünüyor, yüklenen düz dosyaların gerçek boyutu göz önüne alındığında bana garip gelebilir gibi ... Endeksler küçük (Ben değilim ' t Benim durumumda yardım daha bir engel olurdu gibi ek olanlar yarattı) bu yüzden sadece büyük olan gerçek tablolar sanırım ... Yardımınız için bir milyon teşekkürler!
Andrija_Bgd

Veritabanları düz dosyalardan daha fazla yer kaplar. Sayfa yapısı nedeniyle satır ve tablo yapıları için belirli bir miktar ek yük ve belirli bir miktar atık vardır.
Kenneth Fisher

-1

SQL Management Studio'yu kullanarak 1. Veritabanına sağ tıklayın, ardından 2. Görevler-> Shrink -> Dosyalara tıklayın

Şunları gösteren bir iletişim kutusu göreceksiniz: a. Halen Tahsis Edilen Alan b. Kullanılabilir Boş Alan + (% ücretsiz)

% Free değeriniz% 50'nin üzerindeyse dosyayı küçültmeyi düşünebilirsiniz. Bu isabetin% 90 kadar olduğunu gördüm. Dosyayı küçültmeye karar verirsem, genellikle mevcut tahsis edilen alandan 2 veya 3 gig daha fazla ayarladım. Veritabanlarımın çoğu 50gig'den az. Çok daha büyük bir dosyanız varsa, o zaman 10 gig büyük olabilir. Genellikle sadece veritabanını başka bir sunucuya taşıyacaksam küçülme konusunda endişeleniyorum, herhangi bir sql sayfasında küçülme sorunları hakkında her şeyi okuyabilirsiniz.

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.