删除表字段后声明磁盘空间

use*_*182 17 sql-server shrink sql-server-2008-r2

我正在运行 sql 2008 r2 并且数据库在过去 3 年中运行良好且快速,直到大约 3 个月前我们在非常活跃和使用过的表上添加了 ntext 字段。现在我们开始用尽服务器空间,因为这个表的大小越来越大。

我读到了缩小,我们不想放松 db 的索引,因为它多年来一直在快速工作,而且我们不想让碎片消耗殆尽。

我们决定删除该字段及其所有值: 有没有办法删除 ntext 字段及其所有值并释放空间而不删除索引,不缩小,不损失数据库性能?

我附上 db size 查询输出,以显示过去 5 个月的大小扩展。

在此处输入图片说明

Kin*_*hah 14

我们决定删除该字段及其所有值:有没有办法删除 ntext 字段及其所有值并释放空间而不删除索引,不缩小,不损失数据库性能?

我建议使用(来自 BOL : )

DBCC CLEANTABLE
(
    { database_name | database_id | 0 }
    , { table_name | table_id | view_name | view_id }
    [ , batch_size ]
)
[ WITH NO_INFOMSGS ]
Run Code Online (Sandbox Code Playgroud)

DBCC CLEANTABLE 在删除可变长度列后回收空间。可变长度列可以是以下数据类型之一:varchar、nvarchar、varchar(max)、nvarchar(max)、varbinary、varbinary(max)、text、ntext、image、sql_variant 和 xml。删除固定长度列后,该命令不会回收空间。

!! 注意!!使用谨慎的批量大小- 如果您的表很大,建议使用此参数)

DBCC CLEANTABLE 作为一个或多个事务运行。如果指定批处理大小,则该命令在一个事务中处理整个表,并且在操作期间该表被独占锁定。对于一些大表,单个事务的长度和所需的日志空间可能太多。如果指定了批处理大小,该命令将在一系列事务中运行,每个事务包括指定的行数。DBCC CLEANTABLE 不能作为另一个事务内的事务运行。

此操作已完全记录。

一个简单的重现将证明这DBCC CLEANTABLE比 SHRINKING 更好(并且不用担心碎片:-)

-- 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
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

在此处输入图片说明

--drop the ntext column
ALTER TABLE dbo.Test DROP COLUMN col3 ;
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

在此处输入图片说明

--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') ;
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

在此处输入图片说明


Spö*_*rri 6

对于大多数部分,我参考了 Paul Randall 的Inside the storage engine博客系列。

从 SQLServer 中的数据库文件中回收未使用空间的唯一方法是使用 DBCC SHRINK 命令,该命令在释放页面的数据库文件中重新分配数据,并在将它们从全局分配映射中删除后将它们从数据库文件中删除。此操作很慢,会在数据库中产生碎片,并且在处理 LOB 页面时甚至更慢,因为这些页面作为链接列表存储在数据库文件中。

由于您要删除 NTEXT 列,因此您必须等待 ghost 清理过程在缩小之前删除数据。

现在,数据库文件中有大量可用空间实际上对您没有害处,如果您有磁盘空间,备份压缩将处理文件中的可用空间。

如果您绝对想让文件更小,您可以使用数据库创建一个新文件组并将其设为默认值,然后将表移动到新文件组中,但这可能需要时间并导致停机。我使用了Bob Pusateri 在这里解释的技术,结果很好。