Zajęcie miejsca na dysku po usunięciu pola tabeli

16

Używam sql 2008 R2 i db działał dobrze i szybko przez ostatnie 3 lata, aż do około 3 miesięcy temu dodaliśmy pole ntext na bardzo aktywnej i używanej tabeli. Teraz zaczynamy wychodzić z miejsca na serwerze z powodu ogromnego powiększającego się rozmiaru tej tabeli.

Czytałem, że kurczenie się, nie chcemy stracić indeksowania db, ponieważ działał on szybko przez lata i nie chcemy, aby fragmentacja się wydłużyła.

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?

Załączam dane wyjściowe zapytania o rozmiar bazy danych, aby pokazać powiększanie się rozmiaru z ostatnich 5 miesięcy.

wprowadź opis zdjęcia tutaj

użytkownik1021182
źródło

Odpowiedzi:

12

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

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

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

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

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

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Kin Shah
źródło
Po wykonaniu polecenia DBCC CLEANTABLE musisz ODBUDOWAĆ indeks klastrowany na wypadek, gdyby tabela go zawierała, aby odzyskać miejsce. ALTER INDEX IndexName ON YourTable REBUILD;
Pan TA
6

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 .

Spörri
źródło
czy proces czyszczenia duchów zmniejszy przestrzeń, czy też zmniejszy się również?
user1021182,
zawsze będziesz musiał się zmniejszyć, proces czyszczenia tylko opróżnia przydzielone strony, ale nie usuwa ich z plików bazy danych
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.Proszę zobaczyć moją odpowiedź . Możesz użyć, DBCC CLEANTABLEaby zwolnić miejsce.
Kin Shah,
4

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.

Kenneth Fisher
źródło
zostało nam tylko 10 GB miejsca na dysku i skończy się również za kilka dni. usunęliśmy wszystko, co moglibyśmy usunąć z serwera, użyliśmy czyszczenia i zatrzymaliśmy aktualizacje systemu Windows, usunęliśmy je wszystkie i wyczyściliśmy winsxs, teraz musimy zmniejszyć rozmiar pliku db
użytkownik1021182
Ponownie pamiętaj, że po usunięciu dodatkowej kolumny wzrost bazy danych zatrzyma się na jakiś czas, gdy wypełnisz zwolnione miejsce. Jeśli twoja baza danych nadal rośnie po tym momencie, będziesz absolutnie potrzebował dodatkowego miejsca na dysku dla bazy danych. Ewentualnie dodaj nowy dysk do swojego serwera.
Kenneth Fisher
0

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.

ardochhigh
źródło
w takim przypadku wszystkie indeksy również będą musiały zostać przygotowane
użytkownik1021182
tak że wszelkie wskaźniki wpływające na stół będą musiały zostać usunięte i odtworzył również .... odnosi się także do innych obiektów odwołuje się do tabeli np wyzwalaczy
ardochhigh