Mengklaim ruang disk setelah menghapus bidang tabel

16

Saya menjalankan sql 2008 r2 dan db bekerja dengan baik dan cepat selama 3 tahun terakhir sampai sekitar 3 bulan yang lalu kami menambahkan bidang ntext pada tabel yang sangat aktif dan digunakan. Sekarang kita mulai keluar dari ruang server karena ukuran tabel yang sangat besar ini.

Saya membaca bahwa menyusut, kami tidak ingin kehilangan pengindeksan db karena itu bekerja cepat selama bertahun-tahun dan kami tidak ingin mendapatkan pengeluaran fragmentasi.

Kami memutuskan untuk menghapus bidang itu dan semua nilainya: Apakah ada cara untuk menghapus bidang ntext dan semua nilainya serta melepaskan ruang tanpa menghapus indeks, tanpa menyusut, tanpa kehilangan kinerja db?

Saya melampirkan output permintaan ukuran db untuk menunjukkan kepada Anda ukuran ekspansi 5 bulan terakhir.

masukkan deskripsi gambar di sini

pengguna1021182
sumber

Jawaban:

12

Kami memutuskan untuk menghapus bidang itu dan semua nilainya: Apakah ada cara untuk menghapus bidang ntext dan semua nilainya serta melepaskan ruang tanpa menghapus indeks, tanpa menyusut, tanpa kehilangan kinerja db?

Saya akan merekomendasikan untuk menggunakan (dari BOL:)

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

DBCC CLEANTABLE mengambil kembali ruang setelah kolom panjang variabel dijatuhkan. Kolom panjang variabel dapat menjadi salah satu dari tipe data berikut: varchar, nvarchar, varchar (max), nvarchar (max), varbinary, varbinary (max), teks, ntext, gambar, sql_variant, dan xml. Perintah tidak mengambil kembali ruang setelah kolom dengan panjang tetap dijatuhkan.

!! HATI-HATI !! ( gunakan ukuran batch yang cermat - disarankan untuk menggunakan parameter ini jika tabel Anda besar-besaran) :

DBCC CLEANTABLE berjalan sebagai satu atau lebih transaksi. Jika ukuran batch tidak ditentukan, perintah memproses seluruh tabel dalam satu transaksi dan tabel dikunci secara eksklusif selama operasi . Untuk beberapa tabel besar, panjang transaksi tunggal dan ruang log yang dibutuhkan mungkin terlalu banyak. Jika ukuran batch ditentukan, perintah dijalankan dalam serangkaian transaksi, masing-masing termasuk jumlah baris yang ditentukan. DBCC CLEANTABLE tidak dapat dijalankan sebagai transaksi di dalam transaksi lain.

Operasi ini sepenuhnya dicatat.

Repro sederhana akan membuktikan bahwa DBCC CLEANTABLEitu lebih baik daripada MENGHANCURKAN (dan tidak khawatir akan fragmentasi :-)

-- 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

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

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

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

--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') ;

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Kin Shah
sumber
Setelah Anda menjalankan perintah DBCC CLEANTABLE, Anda perlu MEMBANGUN KEMBALI indeks cluster Anda jika ada tabel, untuk mendapatkan kembali spasi. ALTER INDEXNama Nama Indeks PADA DATA ANDA BANGUN KEMBALI;
Tn. TA
6

Untuk sebagian besar, saya mereferensikan seri blog mesin penyimpanan Paul Randall's Inside .

Satu-satunya cara untuk mendapatkan kembali ruang yang tidak terpakai dari file database di SQLServer adalah menggunakan perintah DBCC SHRINK yang merealokasi data di dalam file database yang membebaskan halaman dan setelah menghapusnya dari peta Global Allcation menghapusnya dari file database. Operasi ini lambat, menciptakan fragmentasi dalam database dan bahkan lebih lambat ketika berhadapan dengan halaman LOB karena disimpan sebagai daftar tertaut dalam file database.

Karena Anda menjatuhkan kolom NTEXT, Anda harus menunggu proses pembersihan hantu untuk menjatuhkan data sebelum menyusut.

Sekarang memiliki banyak ruang kosong dalam file database sebenarnya tidak akan membahayakan Anda, jika Anda memiliki ruang disk, kompresi cadangan akan menjaga ruang kosong di dalam file.

Jika Anda benar-benar ingin membuat file lebih kecil, Anda dapat membuat grup grup baru dengan database dan menjadikannya default dan kemudian memindahkan tabel ke grup grup baru tetapi ini bisa memakan waktu dan menyebabkan downtime. Saya telah menggunakan teknik yang dijelaskan di sini oleh Bob Pusateri dengan hasil yang baik.

Spörri
sumber
Apakah proses pembersihan hantu akan mengurangi ruang atau menyusut juga akan diperlukan?
user1021182
Anda harus selalu menyusut, Proses pembersihan hanya mengosongkan halaman yang dialokasikan tetapi tidak menghapusnya dari file database
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.Silakan lihat jawaban saya . Anda dapat menggunakan DBCC CLEANTABLEuntuk melepaskan ruang.
Kin Shah
4

Apakah Anda ingin mengecilkan file database karena Anda membutuhkan ruang untuk database lain / file non DB atau karena Anda mengalami masalah dengan database ini kehabisan ruang?

Jika ini yang kedua maka Anda mungkin tidak memiliki masalah sebesar yang Anda pikirkan. Jika saya memperbaiki masalah Anda adalah kapan database perlu tumbuh untuk mendapatkan ruang tambahan untuk data baru. Setelah Anda menghapus kolom, semua ruang yang digunakan oleh kolom itu akan dibebaskan untuk baris baru yang akan ditambahkan ke tabel dalam database. Ini berarti bahwa akan lebih lama sebelum database Anda perlu tumbuh. Sementara itu saya akan mendapatkan ruang tambahan untuk drive data Anda. Sebagian besar database tumbuh seiring waktu dan senang memiliki ruang kosong yang sehat di drive.

Kenneth Fisher
sumber
kami hanya memiliki 10 GB ruang disk yang tersisa dan juga akan habis dalam beberapa hari. kami telah menghapus semua yang dapat kami hapus dari server dan menggunakan pembersihan dan menghentikan pembaruan windows dan remvo semuanya dan membersihkan winxs, kita sekarang harus mengurangi ukuran file db
user1021182
Sekali lagi, ingat bahwa setelah Anda menghapus kolom tambahan, pertumbuhan DB Anda akan berhenti untuk sementara waktu Anda mengisi ruang baru yang Anda bebaskan. Jika DB Anda masih tumbuh setelah titik ini maka Anda benar-benar membutuhkan ruang disk tambahan untuk database Anda. Kemungkinan menambah drive baru ke server Anda.
Kenneth Fisher
0

Saya akan membuat tabel mirror tanpa kolom yang menyinggung, salin semua data ke dalam tabel ini, jatuhkan yang asli dan kemudian ganti nama tabel cermin.

ardochhigh
sumber
dalam hal ini semua indeks juga perlu dipersiapkan
user1021182
ya indeks apa pun yang mempengaruhi tabel perlu dijatuhkan & diciptakan kembali juga .... juga berlaku untuk objek lain yang mereferensikan tabel misalnya: pemicu
ardochhigh