有两个数据库(db1和db2)。 t1是一个数据库(db1)中的表,t2是其他数据库(db2)中的表。表t1和t2相等。所有数据库都在SQL Server 2008中。
表t1有260000行。表t1的总大小(数据空间和索引大小)为440mb,
表t2为空。
从表t1中删除了80000行并添加到表t2(t2存在于数据库db2中)。
现在,表t2的总大小为80mb,但t1的大小为438mb。
为什么表t1的大小只减少2mb?
我缩小了数据库db1,但表t1的大小没有减少。
现在我可以减小表t1的大小吗?
答案 0 :(得分:1)
如果80000在t1
中的整个群集密钥中随机分布,那么您可能实际上没有释放多个页面。如果要释放任何空间,可能需要在t1
上重建/重新组织群集和非群集索引。
举一个表格被弹出的简单例子
IF OBJECT_ID(N'dbo.T', 'U') IS NOT NULL
DROP TABLE dbo.T;
CREATE TABLE dbo.T
(
ID INT IDENTITY(1, 1) NOT NULL,
Filler CHAR(1000),
CONSTRAINT PK_T__ID PRIMARY KEY CLUSTERED (ID)
);
INSERT dbo.T (Filler)
SELECT TOP 100000 REPLICATE('|', 1000)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b;
EXECUTE sp_spaceused @objname = N'dbo.T';
name rows reserved data index_size unused
T 100000 114768 KB 114288 KB 440 KB 40 KB
现在删除20,000个随机行并再次检查:
DELETE t
FROM ( SELECT TOP 20000 ID
FROM dbo.T
ORDER BY NEWID()
) AS t;
EXECUTE sp_spaceused @objname = N'dbo.T';
name rows reserved data index_size unused
T 80000 114768 KB 114288 KB 440 KB 40 KB
你可以看到,尽管没有删除20%的数据,但实际上并没有删除任何数据。如果我们重建索引以摆脱碎片,我们将看到尺寸减小:
ALTER INDEX PK_T__ID ON dbo.T REBUILD;
EXECUTE sp_spaceused @objname = N'dbo.T';
name rows reserved data index_size unused
T 80000 91664 KB 91432 KB 176 KB 56 KB
对于最后一个,你的milage可能会有所不同,因为它实际上取决于删除行的位置以及释放了多少页面,但希望你能得到图片。如果你需要释放空间,你需要整理碎片。
MSDN recommends重建碎片超过30%,并在5%到30%之间重新组织。但是,我已经阅读过关于SQL Server性能(网站当前已关闭,因此无法链接)的信息,因为重建可以利用并行性,实际上更有效地进行重建。< / p>
答案 1 :(得分:-1)
USE [master]
GO
ALTER DATABASE [db1] SET RECOVERY SIMPLE WITH NO_WAIT
DBCC SHRINKFILE(db1, 1)
ALTER DATABASE [db1] SET RECOVERY FULL WITH NO_WAIT
GO
试试这个,