Zdecydowaliśmy się usunąć to pole i wszystkie jego wartości: Czy istnieje sposób na usunięcie pola ntext i wszystkich jego wartości oraz zwolnienie miejsca bez usuwania indeksowania, bez zmniejszania, bez utraty wydajności bazy danych?
Poleciłbym użyć (z BOL:)
DBCC CLEANTABLE
(
{ database_name | database_id | 0 }
, { table_name | table_id | view_name | view_id }
[ , batch_size ]
)
[ WITH NO_INFOMSGS ]
DBCC CLEANTABLE odzyskuje przestrzeń po upuszczeniu kolumny o zmiennej długości. Kolumna o zmiennej długości może być jednym z następujących typów danych: varchar, nvarchar, varchar (max), nvarchar (max), varbinary, varbinary (max), text, ntext, image, sql_variant i xml. Polecenie nie odzyskuje miejsca po upuszczeniu kolumny o stałej długości.
!! UWAGA !! ( użyj ostrożnego rozmiaru partii - wskazane jest użycie tego parametru, jeśli twoja tabela jest ogromna) :
DBCC CLEANTABLE działa jako jedna lub więcej transakcji. Jeśli rozmiar partii nie jest określony, polecenie przetwarza całą tabelę w jednej transakcji, a tabela jest blokowana wyłącznie podczas operacji . W przypadku niektórych dużych tabel długość pojedynczej transakcji i wymagane miejsce w dzienniku mogą być zbyt duże. Jeśli określono wielkość partii, polecenie jest uruchamiane w szeregu transakcji, z których każda obejmuje określoną liczbę wierszy. DBCC CLEANTABLE nie może być uruchamiany jako transakcja wewnątrz innej transakcji.
Ta operacja jest w pełni zalogowana.
Proste repro udowodni, że DBCC CLEANTABLE
jest lepsze niż SHRINKING (i nie martw się fragmentacją :-)
-- 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') ;