在我的数据库最初我有三列一个表,当时的MDF文件大小为5122 KB的数据。SQL MDF文件大小不改变
,我已插入50万条记录在此表中,MDF文件大小增加至19456 KB
然后,我已经更新了我的表,由一列的所有值作为空但文件大小仍是相同的,即19456 KB。
然后我从这个表中删除所有记录,但我的MDF文件的大小仍然是19456 KB。
我想知道为什么文件的大小没有改变? 列中的空值是否占用空间?
在我的数据库最初我有三列一个表,当时的MDF文件大小为5122 KB的数据。SQL MDF文件大小不改变
,我已插入50万条记录在此表中,MDF文件大小增加至19456 KB
然后,我已经更新了我的表,由一列的所有值作为空但文件大小仍是相同的,即19456 KB。
然后我从这个表中删除所有记录,但我的MDF文件的大小仍然是19456 KB。
我想知道为什么文件的大小没有改变? 列中的空值是否占用空间?
要收回你需要收缩数据库,因为这是不是出于性能方面的自动完成的空间。
的更多信息:
是否在列Null值需要空间?
AUTO_SHRINK
开启的MDF文件不会自动收缩以下行的删除(which you shouldn't!)
至于是否空值占用这取决于数据类型的空间。在固定长度的列中,仍然会为包含NULL值的行中的列分配全部空间量。对于可变的它不会。
但即使是可变长度列简单的列值更新为NULL
可能会离开你的内部碎片在自由空间通过数据页散落。
要看到这一点:
创建表脚本:
CREATE TABLE dbo.t
(
id INT IDENTITY PRIMARY KEY,
vc VARCHAR(4000)
)
INSERT INTO t
SELECT TOP 26 replicate(char(64 + row_number() OVER(ORDER BY (SELECT 0))), 4000) AS rn
FROM sys.objects
查看分配的页:
SELECT CONVERT(CHAR(10), object_name(i.object_id)) AS table_name,
CONVERT(CHAR(16), i.name) AS index_name,
i.index_id,
CONVERT(CHAR(10), i.type_desc) AS index_type,
partition_number AS pnum,
rows,
CONVERT(CHAR(12), a.type_desc) AS page_type_desc,
total_pages AS pages
FROM sys.indexes i
JOIN sys.partitions p
ON i.object_id = p.object_id
AND i.index_id = p.index_id
JOIN sys.allocation_units a
ON p.partition_id = a.container_id
WHERE i.object_id = object_id('dbo.t');
返回:
table_name index_name index_id index_type pnum rows page_type_desc pages
---------- ---------------- ----------- ---------- ----------- -------------------- -------------- --------------------
t PK__t__7C8480AE 1 CLUSTERED 1 26 IN_ROW_DATA 17
查看的第一个数据页SQL Internals Viewer
将列设置为空
UPDATE t SET vc=NULL
前面的查询显示,17页仍然分配
在SQL内幕再次查看第一个数据页浏览器
可以看出,原始数据仍然存在并有行无自动重排,以回收空间。
+1非常好的答案,并教我一个新的工具。 – 2010-09-18 15:28:21