Chúng tôi đã quyết định xóa trường đó và tất cả các giá trị của nó: Có cách nào để xóa trường ntext và tất cả các giá trị của nó và giải phóng không gian mà không xóa chỉ mục, không thu hẹp, không mất hiệu năng db?
Tôi muốn giới thiệu để sử dụng (từ BOL :)
DBCC CLEANTABLE
(
{ database_name | database_id | 0 }
, { table_name | table_id | view_name | view_id }
[ , batch_size ]
)
[ WITH NO_INFOMSGS ]
DBCC R CLE RÀNG lấy lại không gian sau khi cột có độ dài thay đổi được loại bỏ. Cột có độ dài thay đổi có thể là một trong các loại dữ liệu sau: varchar, nvarchar, varchar (max), nvarchar (max), varbinary, varbinary (max), text, ntext, image, sql_variant và xml. Lệnh không lấy lại khoảng trống sau khi cột có độ dài cố định bị hủy.
!! THẬN TRỌNG !! ( sử dụng kích thước lô cẩn thận - nên sử dụng tham số này nếu bảng của bạn lớn) :
DBCC CLEANTABLE chạy dưới dạng một hoặc nhiều giao dịch. Nếu kích thước lô không được chỉ định, lệnh sẽ xử lý toàn bộ bảng trong một giao dịch và bảng bị khóa độc quyền trong quá trình hoạt động . Đối với một số bảng lớn, độ dài của giao dịch đơn và không gian nhật ký cần thiết có thể quá nhiều. Nếu một kích thước lô được chỉ định, lệnh sẽ chạy trong một loạt các giao dịch, mỗi giao dịch bao gồm số lượng hàng được chỉ định. DBCC CLEANTABLE không thể được chạy như một giao dịch bên trong một giao dịch khác.
Hoạt động này được ghi lại đầy đủ.
Một repro đơn giản sẽ chứng minh rằng DBCC CLEANTABLE
nó tốt hơn SHRINKING (và không phải lo lắng về sự phân mảnh :-)
-- 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
--drop the ntext column
ALTER TABLE dbo.Test DROP COLUMN col3 ;
--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') ;