Wir haben beschlossen, dieses Feld und alle seine Werte zu löschen: Gibt es eine Möglichkeit, das ntext-Feld und alle seine Werte zu löschen und Speicherplatz freizugeben, ohne die Indizierung zu entfernen, ohne die Datenbankleistung zu verringern?
Ich würde empfehlen (von BOL:)
DBCC CLEANTABLE
(
{ database_name | database_id | 0 }
, { table_name | table_id | view_name | view_id }
[ , batch_size ]
)
[ WITH NO_INFOMSGS ]
DBCC CLEANTABLE beansprucht Speicherplatz zurück, nachdem eine Spalte mit variabler Länge gelöscht wurde. Eine Spalte variabler Länge kann einen der folgenden Datentypen haben: varchar, nvarchar, varchar (max), nvarchar (max), varbinary, varbinary (max), text, ntext, image, sql_variant und xml. Der Befehl beansprucht keinen Speicherplatz mehr, nachdem eine Spalte mit fester Länge gelöscht wurde.
!! VORSICHT !! ( Verwenden Sie eine sorgfältige Stapelgröße - es ist ratsam, diesen Parameter zu verwenden, wenn Ihre Tabelle sehr umfangreich ist) :
DBCC CLEANTABLE wird als eine oder mehrere Transaktionen ausgeführt. Wenn eine Chargengröße wird nicht angegeben, verarbeitet der Befehl die gesamte Tabelle in einer Transaktion und der Tisch ausschließlich während des Betriebes gesperrt ist . Bei einigen großen Tabellen können die Länge der einzelnen Transaktion und der erforderliche Protokollspeicherplatz zu groß sein. Wenn eine Stapelgröße angegeben ist, wird der Befehl in einer Reihe von Transaktionen ausgeführt, die jeweils die angegebene Anzahl von Zeilen enthalten. DBCC CLEANTABLE kann nicht als Transaktion in einer anderen Transaktion ausgeführt werden.
Dieser Vorgang wird vollständig protokolliert.
Eine einfache Reproduktion wird beweisen, dass dies DBCC CLEANTABLE
besser ist als das Schrumpfen (und keine Sorge vor Fragmentierung :-)
-- 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') ;
Für die meisten Teile beziehe ich mich auf Paul Randalls Blogserie Inside the Storage Engine .
Die einzige Möglichkeit, nicht verwendeten Speicherplatz aus Datenbankdateien in SQLServer zurückzugewinnen, besteht in der Verwendung des Befehls DBCC SHRINK, mit dem Daten in den Datenbankdateien neu zugeordnet und nach dem Entfernen aus der Global Allcation-Zuordnung aus der Datenbankdatei entfernt werden. Dieser Vorgang ist langsam, führt zu einer Fragmentierung in der Datenbank und ist sogar langsamer, wenn LOB-Seiten verarbeitet werden, da diese als verknüpfte Listen in den Datenbankdateien gespeichert werden.
Da Sie die NTEXT-Spalte löschen, müssen Sie vor dem Verkleinern warten, bis der Bereinigungsprozess für Geisterbilder die Daten gelöscht hat.
Wenn Sie jetzt viel freien Speicherplatz in den Datenbankdateien haben, schadet dies nicht. Wenn Sie über den Festplattenspeicher verfügen, wird durch die Sicherungskomprimierung der freie Speicherplatz in den Dateien berücksichtigt.
Wenn Sie die Dateien unbedingt verkleinern möchten, können Sie eine neue Dateigruppe mit der Datenbank erstellen und als Standard festlegen. Verschieben Sie dann die Tabellen in die neue Dateigruppe. Dies kann jedoch Zeit in Anspruch nehmen und Ausfallzeiten verursachen. Ich habe die hier von Bob Pusateri erläuterte Technik mit guten Ergebnissen angewendet .
quelle
Since you are dropping the NTEXT column you will have to wait for the ghost cleanup process to drop the data before shrinking.
Bitte siehe meine Antwort . Sie können verwendenDBCC CLEANTABLE
, um den Raum freizugeben.Möchten Sie die Datenbankdateien verkleinern, weil Sie diesen Speicherplatz für andere Datenbanken / Nicht-DB-Dateien benötigen oder weil Sie Probleme mit der Ausführung dieser Datenbank haben?
Wenn es das zweite ist, haben Sie möglicherweise kein so großes Problem, wie Sie denken. Wenn ich richtig liege, besteht Ihr Problem darin, dass die Datenbank erweitert werden muss, um zusätzlichen Speicherplatz für neue Daten zu gewinnen. Sobald Sie die Spalte entfernen, wird der gesamte von dieser Spalte belegte Speicherplatz für neue Zeilen freigegeben, die Tabellen in der Datenbank hinzugefügt werden. Dies bedeutet, dass es länger dauern wird, bis Ihre Datenbank wachsen muss. In der Zwischenzeit würde ich etwas zusätzlichen Platz für Ihr Datenlaufwerk bekommen. Die meisten Datenbanken wachsen mit der Zeit und es ist schön, über einen gesunden freien Speicherplatz auf dem Laufwerk zu verfügen.
quelle
Ich würde eine Spiegeltabelle ohne die anstößige Spalte erstellen, alle Daten in diese Tabelle kopieren, das Original löschen und dann die Spiegeltabelle umbenennen.
quelle