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') ;
W większości przypadków odwołuję się do serii blogów Inside the Storage Engine Paula Randalla .
Jedynym sposobem na odzyskanie nieużywanego miejsca z plików bazy danych w SQLServer jest użycie komendy DBCC SHRINK, która przenosi dane w plikach bazy danych, zwalniając strony, a po usunięciu ich z mapy Global Allcation usuwa je z pliku bazy danych. Ta operacja jest powolna, powoduje fragmentację bazy danych, a nawet wolniejsza w przypadku stron LOB, ponieważ są one przechowywane jako połączone listy w plikach bazy danych.
Ponieważ upuszczasz kolumnę NTEXT, będziesz musiał poczekać, aż proces czyszczenia ducha usunie dane, zanim się zmniejszy.
Teraz posiadanie dużej ilości wolnego miejsca w plikach bazy danych nie zaszkodzi, jeśli masz miejsce na dysku, kompresja kopii zapasowych zajmie się wolnym miejscem w plikach.
Jeśli absolutnie chcesz zmniejszyć pliki, możesz utworzyć nową grupę plików z bazą danych i ustawić ją jako domyślną, a następnie przenieść tabele do nowej grupy plików, ale może to zająć trochę czasu i spowodować przestoje. Z dobrymi wynikami zastosowałem technikę objaśnioną przez Boba Pusateri .
źródło
Since you are dropping the NTEXT column you will have to wait for the ghost cleanup process to drop the data before shrinking.
Proszę zobaczyć moją odpowiedź . Możesz użyć,DBCC CLEANTABLE
aby zwolnić miejsce.Czy chcesz zmniejszyć pliki bazy danych, ponieważ potrzebujesz tego miejsca na inne bazy danych / pliki inne niż DB lub ponieważ masz problemy z brakiem miejsca w tej bazie danych?
Jeśli jest to drugi, to możesz nie mieć tak dużego problemu, jak myślisz. Jeśli mam rację, to problem polega na tym, że baza danych musi się powiększać, aby zyskać dodatkowe miejsce na nowe dane. Po usunięciu kolumny całe miejsce zajmowane przez tę kolumnę zostanie zwolnione na dodanie nowych wierszy do tabel w bazie danych. Oznacza to, że minie więcej czasu, zanim baza danych będzie musiała rosnąć. W międzyczasie uzyskałbym dodatkowe miejsce na dysku z danymi. Większość baz danych rośnie z czasem i dobrze jest mieć zdrowy margines wolnego miejsca na dysku.
źródło
Chciałbym utworzyć tabelę lustrzaną bez obrażającej kolumny, skopiować wszystkie dane do tej tabeli, upuścić oryginał, a następnie zmienić nazwę tabeli lustrzanej.
źródło