天天看點

SQL Server中sp_spaceused統計資料使用的空間總量不正确的原因

很多時候,我們經常使用sp_spaceused來檢視表的空間使用情況,上個月群裡有個網友說他使用DELETE删除了資料後,使用sp_spaceused檢視,發現該表的配置設定的空間總量(reserved)與資料使用的空間總量(data)沒有變化,當時和他讨論了并分析了一下原因,随手記錄了一下這個案例,這個周末剛好有點時間,正好分析整理一下這個案例、分享在這篇文章。如下所示,我們先構造資料,我們的測試案例比較極端,剛剛保證每個頁面(page)剛好存儲兩條記錄。如下所示:

EXEC sp_spaceused 'dbo.space_test'

SQL Server中sp_spaceused統計資料使用的空間總量不正确的原因
SQL Server中sp_spaceused統計資料使用的空間總量不正确的原因

接下來我們删除了id為偶數的記錄。

DELETE dbo.space_test WHERE id %2=0

如下截圖所示,我們删除了5000條記錄,還剩下5000條記錄,但是該表的配置設定的空間總量(reserved)與資料使用的空間總量(data)沒有變化,依然是40008KB和40000KB

SQL Server中sp_spaceused統計資料使用的空間總量不正确的原因

我們删除了一半記錄,照理說,資料使用的空間總量(data)應該變化了。那麼我使用DBCC SHOWCONTIG('space_test')來看看,如下截圖所示,

你會發現每頁的平均可用位元組數(Avg. Bytes Free per Page) 和平均頁密度(滿)(Avg. Page Density (full))出現了變化。如下對比所示:

<b> </b>

<b>Avg. Bytes Free per Page</b><b></b>

<b>Avg. Page Density (full)</b><b></b>

<b>删除前</b><b></b>

62

99.23%

<b>删除後</b><b></b>

4077.8

49.62%

SQL Server中sp_spaceused統計資料使用的空間總量不正确的原因

我們知道sp_spaceused的精确機關是頁。它是根據sys.allocation_units 和sys.partitions 這兩張管理視圖來計算存儲空間的。有時候,這兩張表可能不能及時反映出資料的準确資訊。可以通過updateusage這個參數,要求SQL Server為這個指令更新管理視圖裡的統計資訊。但是這個案例中,sp_spaceused不準确的原因并不是因為這兩張表沒有及時反映出資料的準确資訊,而是實驗中按照特殊規律,在每一頁都删除一條記錄,保留一條記錄,導緻每一頁上釋放了接近一半的空間,并且頁的填充程度接近50%,進而出現頁面碎片化非常嚴重的情況,而sp_spaceused的精确機關是頁,進而導緻這種特殊的情況出現。

其實這個倒沒有必要大驚小怪,這個空間雖然沒有釋放,但是下次依然可以再次利用,就好比一列火車,每節車廂隻載了一半乘客,後面的路程中,可以繼續往裡面加入新的乘客。如下所示我們插入5000條記錄,你會發現頁的平均密度變化了,之前空閑的空間被重新利用了。

SQL Server中sp_spaceused統計資料使用的空間總量不正确的原因