2011-02-15 57 views
6

我有一個表超過30萬條記錄,大小約1.5 GB回收未使用的空間在SQL Server 2008

在該表中我有三個varchar(5000)場,其餘均爲小型油田。

在簽發update時,將這三個字段設置爲''

收縮(數據庫和文件),數據庫使用幾乎相同的空間之前之後...

DBCC SHRINKDATABASE(N'DataBase') 
DBCC SHRINKFILE (N'DataBase' , 1757) 
DBCC SHRINKFILE (N'DataBase_log' , 344) 

如何收回磁盤空間的任何想法?

回答

3

實質上,您必須將表格的內容從硬盤上的某個位置「移動」到另一個位置。當如此移動時,SQL將有效地「重新包裝」頁面的內容。只需用3(或0和翻轉的空位掩碼)替換5000字節的數據不會導致SQL修改或重寫表的頁面內容。

如果表中有一個聚簇索引,只需重新索引它(ALTER INDEX ... REBUILD ...)就可以實現。

如果該表沒有聚集索引,則可以創建一個然後刪除它,或者SELECT ... INTO ...新表,刪除舊錶,然後將新表重命名爲原始表名稱。

+0

是的,「移動內容」是答案,更改聚集索引是一個很好的提示,我改變了數據庫的結構(sql manager創建了一個drop並重新創建腳本...) – opensas 2011-02-16 00:41:03

0

我剛剛來設置這些字段爲空,發出收縮,然後將它們設置爲'

和DB 1.5 GB跑到115 MB

非常奇怪...

- 事實上

,設置這些字段可空手段 - 即重建整個表 - 沒招

+0

不知道這裏有沒有什麼區別,但是你的表是堆還是有聚簇索引? – 2011-02-15 23:41:38

2

只是因爲你設置列爲零並不意味着數據庫將重新組織表格。更新後的記錄仍然適合之前所適用的同一頁面(頁面上的可用空間量將增加)。

此外,你知道,你不知道,varchar(5000)並不意味着它需要5000個八位字節?它是可變長度 - 一個包含字段數據長度的兩字節長度前綴,後跟數據字節。將行中的varchar(5000)列設置爲'foobar'將需要8個八位字節的空間(2 + 6)。

重新構建您的索引,包括聚類索引。

如果您沒有羣集索引,請添加一個。這將迫使表格重新組合。現在刪除聚類索引。

現在,當您收縮數據文件時,您應該回收一些磁盤空間。

+0

yeap,我知道varchar是變量......這就是爲什麼我儘管清空varchar字段應該足以減少表的大小...... – opensas 2011-02-16 00:39:27