Tablo alanını kaldırdıktan sonra disk alanı talep etme


16

Ben sql 2008 r2 çalıştırıyorum ve db yaklaşık 3 ay öncesine kadar son 3 yıldır iyi ve hızlı çalışıyordu çok aktif ve kullanılmış tablo ntext alanı ekledik. Şimdi bu tablonun genişleyen boyutu nedeniyle sunucu alanından çıkmaya başlıyoruz.

Daralan okudum, db'nin indekslenmesini kaybetmek istemiyoruz çünkü yıllarca hızlı çalışıyor ve parçalanma harcamaları almak istemiyoruz.

Bu alanı ve tüm değerlerini silmeye karar verdik: Ntext alanını ve tüm değerlerini silmenin ve alanı indekslemeyi kaldırmadan, küçülmeden, db performansını kaybetmeden silmenin bir yolu var mı?

Ben son 5 ay boyut genişleme göstermek için db boyutu sorgu çıktı ekliyorum.

resim açıklamasını buraya girin

Yanıtlar:


12

Bu alanı ve tüm değerlerini silmeye karar verdik: Ntext alanını ve tüm değerlerini silmenin ve alanı indekslemeyi kaldırmadan, küçülmeden, db performansını kaybetmeden silmenin bir yolu var mı?

(BOL: 'dan) tavsiye ederim

DBCC CLEANTABLE
(
    { database_name | database_id | 0 }
    , { table_name | table_id | view_name | view_id }
    [ , batch_size ]
)
[ WITH NO_INFOMSGS ]

DBCC CLEANTABLE, değişken uzunlukta bir sütun bırakıldıktan sonra alanı geri kazanır. Değişken uzunlukta bir sütun aşağıdaki veri türlerinden biri olabilir: varchar, nvarchar, varchar (max), nvarchar (max), varbinary, varbinary (max), metin, ntext, resim, sql_variant ve xml. Sabit uzunlukta bir sütun bırakıldıktan sonra komut alanı geri almaz.

!! DİKKAT !! ( dikkatli bir toplu iş boyutu kullanın - tablonuz çok büyükse bu parametreyi kullanmanız önerilir) :

DBCC CLEANTABLE bir veya daha fazla işlem olarak çalışır. Bir parti boyutu ise değildir belirtilen, komut bir işlemde bütün tablo işler ve tablo özel işlem sırasında kilitlenir . Bazı büyük tablolar için, tek işlemin uzunluğu ve gereken günlük alanı çok fazla olabilir. Bir toplu iş boyutu belirtilirse, komut, her biri belirtilen sayıda satır içeren bir dizi işlemde çalışır. DBCC CLEANTABLE başka bir işlem içinde işlem olarak çalıştırılamaz.

Bu işlem tamamen günlüğe kaydedilir.

Basit bir repro DBCC CLEANTABLESHRINKING (ve parçalanma endişesi yok) daha iyi olduğunu kanıtlayacaktır :-)

-- clean up
drop table dbo.Test

-- create test table with ntext column that we will drop later
create table dbo.Test (
    col1 int
    ,col2 char(25)
    ,col3 ntext
    );

-- insert  1000 rows of test data
declare @cnt int;

set @cnt = 0;

while @cnt < 1000
begin
    select @cnt = @cnt + 1;

    insert dbo.Test (
        col1
        ,col2
        ,col3
        )
    values (
        @cnt
        ,'This is a test row # ' + CAST(@cnt as varchar(10)) + 'A'
        ,REPLICATE('KIN', ROUND(RAND() * @cnt, 0))
        );
end

resim açıklamasını buraya girin

resim açıklamasını buraya girin

--drop the ntext column
ALTER TABLE dbo.Test DROP COLUMN col3 ;

resim açıklamasını buraya girin

resim açıklamasını buraya girin

--reclaim the space from the table
-- Note that my table is only having 1000 records, so I have not used a batch size
-- YMMV .. so find a maintenance window and you an appropriate batch size 
-- TEST TEST and TEST before implementing in PROD.. so you know the outcome !!
DBCC CLEANTABLE('tempdb', 'dbo.Test') ;

resim açıklamasını buraya girin

resim açıklamasını buraya girin


DBCC CLEANTABLE komutunu yürüttükten sonra, alanı geri almak için tabloda bir tane olması durumunda kümelenmiş dizininizi YENİDEN YAPMALISINIZ. ALTER INDEX DizinAdı TABLANIZDA YENİLEME;
Sayın TA

6

Çoğu bölüm için Paul Randall'ın Inside the storage engine blog serisine .

Kullanılmayan alanı SQLServer'daki veritabanı dosyalarından geri almanın tek yolu, veritabanı dosyaları içindeki sayfaları serbest bırakan DBCC SHRINK komutunu kullanmaktır ve bunları Global Allcation haritasından kaldırdıktan sonra veritabanı dosyasından kaldırır. Bu işlem yavaştır, veritabanı içinde parçalanma oluşturur ve bunlar LOB sayfaları ile uğraşırken veritabanı dosyalarında bağlantılı listeler olarak saklandıklarında daha da yavaşlar.

NTEXT sütununu düşürdüğünüz için, küçülmeden önce hayalet temizleme işleminin verileri bırakmasını beklemeniz gerekir.

Şimdi veritabanı dosyalarında çok fazla boş alan olması aslında size zarar vermez, disk alanınız varsa, yedekleme sıkıştırması dosyalar içindeki boş alanı halleder.

Dosyaları kesinlikle daha küçük yapmak istiyorsanız, veritabanıyla yeni bir dosya grubu oluşturabilir ve varsayılanı yapabilir ve tabloları yeni dosya grubuna taşıyabilirsiniz, ancak bu zaman alabilir ve çalışmama süresine neden olabilir. Burada Bob Pusateri tarafından açıklanan tekniği iyi sonuçlarla kullandım.


hayalet temizleme işlemi alanı azaltacak mı yoksa küçülecek mi?
user1021182

her zaman küçültmeniz gerekir, Temizleme işlemi yalnızca ayrılan sayfaları boşaltır, ancak veritabanı dosyalarından kaldırmaz
Spörri

1
@ Spörri Since you are dropping the NTEXT column you will have to wait for the ghost cleanup process to drop the data before shrinking.Lütfen cevabımı görün . DBCC CLEANTABLEAlanı serbest bırakmak için kullanabilirsiniz .
Kin Shah

4

Diğer veritabanları / DB olmayan dosyalar için bu alana ihtiyaç duyduğunuzdan veya bu veritabanı ile ilgili alanınız bittiğinde sorun yaşadığınız için veritabanı dosyalarını küçültmek mi istiyorsunuz?

Eğer ikinciyse, düşündüğünüz kadar büyük bir probleminiz olmayabilir. Eğer doğruysam sorun yeni veri için ek alan kazanmak için veritabanı büyümesi gerektiğinde. Sütunu kaldırdığınızda, yeni satırların veritabanındaki tablolara eklenmesi için o sütunun kapladığı alanın tümü serbest bırakılır. Bu, veritabanınızın büyümesi için daha uzun olacağı anlamına gelir. Bu arada veri sürücünüz için biraz ek alan elde ediyorum. Çoğu veritabanı zamanla büyür ve sürücüde sağlıklı bir boş alan payı olması güzeldir.


disk alanımızda sadece 10 gb kaldı ve birkaç gün içinde bitecek. sunucudan kaldırabildiğimiz her şeyi kaldırdık ve temizlemeler kullandık ve windows güncellemelerini durdurduk ve hepsini geri aldık ve winsx'leri temizledik, şimdi db dosyasının boyutunu küçültmeliyiz
user1021182

Yine, ekstra sütunu sildikten sonra, serbest bıraktığınız yeni alanı doldururken DB büyümenizin bir süre duracağını unutmayın. DB'niz bu noktadan sonra hala büyüyorsa, veritabanınız için kesinlikle ek disk alanına ihtiyacınız olacaktır. Muhtemelen sunucunuza yeni bir sürücü ekleyin.
Kenneth Fisher

0

Rahatsız edici sütun olmadan bir ayna tablosu oluşturmak, tüm verileri bu tabloya kopyalamak, orijinali bırakmak ve ayna tablosunu yeniden adlandırmak istiyorum.


bu durumda tüm indekslerin de hazırlanması gerekir
user1021182

evet tabloyu etkileyen herhangi bir dizinler de bırakılması ve yeniden oluşturulması gerekir .... tabloya referans diğer nesneler için de geçerlidir örneğin: tetikler
ardochhigh
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.