SQL Server中sp_spaceused統計數據使用的空間總量不正確的原因


 

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

 

 

USE Test ;
GO
 
CREATE TABLE space_test
(
    id        INT,
    name    VARCHAR(4000)
)
GO
SET NOCOUNT ON;
Go
DECLARE @Index INT ;
SET @Index = 1;
WHILE @Index <= 10000
BEGIN 
    INSERT INTO dbo.space_test
    SELECT @Index, REPLICATE(N'k', 4000);
 
    SET @Index += 1;
END

 

 

 

EXEC sp_spaceused 'dbo.space_test'

 

 

clip_image001

 

 

 

 

clip_image002

 

 

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

 

 

DELETE dbo.space_test WHERE id %2=0

 

 

 

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

 

 

clip_image003

 

 

 

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

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

 

 

Avg. Bytes Free per Page

Avg. Page Density (full)

刪除前

62

99.23%

刪除后

4077.8

49.62%

 

 

clip_image004

 

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

 

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

 

DECLARE @Index INT ;
SET @Index = 2;
WHILE @Index <= 10000
BEGIN 
    INSERT INTO dbo.space_test
    SELECT @Index, REPLICATE(N'k', 4000);
 
    SET @Index += 2;
END
GO

 

 

clip_image005


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM