縮小僅包含 HEAP 的數據庫後,是否需要修復碎片?
我有一個 1 TB 的數據庫,其中包含數百個季度存檔表,我希望刪除任何超過 5 個財務季度的表,這將釋放約 600 GB 的空間。提供表架構的範例:
myTable myTable_Q4_21 myTable_Q3_21 myTable2_Q4_21 myTable2_Q3_21
我想知道在刪除這些表並縮小數據庫以回收新釋放的空間之後,是否需要 ALTER..REBUILD 每個剩餘的 HEAP 表或在每個表上放置一個 CX 並在之後刪除它們。
你需要嗎?不可以。但是考慮將它們替換為具有歸檔壓縮功能的聚集列儲存表。它們將被整理碎片,更小,並且掃描速度更快。
“需要”是非常強烈的措辭。讓我們更具體,然後您可以確定是否要這樣做:
堆不是鍊錶。即,當 SQL Server 訪問堆時,它可以通過 B 樹索引找到行,或者在表掃描時使用 IAM 頁面(堆正在使用的範圍的映射)。
Shrink 將頁面從文件末尾移動到文件開頭(不考慮連結列表的頁面順序)。對於鍊錶(B 樹索引),當 SQL Server 讀取大量頁面(掃描或部分掃描)時,可能會導致 SQL Server 在數據庫文件中“來回跳轉”。對於旋轉磁碟,這可能很糟糕。現代磁碟子系統不那麼糟糕(這就是我們現在較少關注碎片整理的原因)。這就是我們所說的外部碎片。
由於堆沒有“遵循鍊錶”的概念,因此對於堆來說收縮的結果幾乎沒有。當然,與之前相比,堆的頁面最終會在文件中更加分散。但是我們沒有堆的“來回跳躍”方面。還有一些細節,例如 SQL Server 使用 scatter-gather I/O 來最小化數據“傳播”的影響。
還有其他事情,例如您的頁面可能未滿(內部碎片)和轉發記錄(一行已更新,移動到其他位置,並且在舊位置有指向新位置的指針)。這不會因收縮而改變。當然,進行重建可能是有益的,但這些方面並沒有因為你進行收縮而改變。
即,簡短的回答是:收縮不會降低堆的效率。
而且,正如大衛已經提到的那樣,您可能一開始就不希望將這些作為堆…