Sql-Server

什麼時候可以收縮數據庫?

  • May 6, 2019

我知道收縮是魔鬼:它會顛倒頁面順序並導致皮膚癌、數據碎片化和全球變暖。清單還在繼續……話雖如此,假設我有一個 100 GB 的數據庫,我刪除了 50 GB 的數據——不是在一個表上,而是在數據庫範圍內對舊數據進行一般修剪,覆蓋 90%表——這是否構成縮小數據庫的適當案例?

如果不是,那麼在從數據庫中刪除如此高比例的數據後,採取哪些適當的步驟來清理房屋?我可以想到兩個:重建索引和更新統計資訊。還有什麼?

真正不推薦重組和收縮。

如果您可以使數據庫正在離線服務的應用程序,您可以通過在收縮之前刪除所有索引和主/外鍵約束來加快程序並減少索引碎片(這意味著移動的數據更少,因為只有數據頁面將被打亂,而不是現在不存在的索引頁面,加快程序)然後重新創建所有索引和鍵。

在收縮之後重新創建索引意味著它們不應該被嚴重碎片化,並且在收縮期間它們消失意味著重建它們不會在文件中的頁面分配中留下許多可能會在以後引起碎片的小“洞”。

如果您可以使應用程序離線,另一種選擇是將所有數據遷移到具有相同結構的新數據庫中。如果您的建構過程可靠,您應該能夠快速建構該空白數據庫,如果不能從目前數據庫創建一個(恢復目前數據庫的備份,截斷/刪除表中的所有內容並執行完全收縮)。

您可能仍希望刪除目標中的所有索引並在之後重新創建它們,因為在更改大量索引數據(在這種情況下為 100%)時,這樣做會更有效率。為了加快複製過程,將不同物理驅動器上的目標數據庫的數據文件保存到源(除非您使用 SSD,在這種情況下您不需要關心減少頭部移動),您可以移動它們完成後到源位置。

此外,如果將目標創建為新的(而不是通過清空源的副本)創建它,其初始大小將包含所有目前數據加上幾個月的增長 - 這將使數據複製再次更快一點它不會在整個過程中時不時地分配新空間。

這可能比使用收縮更好,因為將數據遷移到新數據庫會複製收縮操作的預期操作,但碎片可能要少得多(這是重組和收縮的意外結果)。收縮只是從文件末尾附近獲取塊並將它們放在靠近開頭的第一個空間中,而不會努力將相關數據保持在一起。

我懷疑結果在空間方面也會更有效,因為之後可能會減少部分使用的頁面。收縮只會移動部分使用的頁面,移動數據更有可能導致完整頁面,特別是如果您按照表的聚集鍵/索引(表有一個)的順序插入目標並創建其他索引數據全部遷移後。

當然,如果您根本無法使應用程序離線,那麼僅執行收縮是您唯一的選擇,因此如果您確實需要回收空間,那就去吧。根據您的數據、訪問模式、常見工作集大小、伺服器有多少 RAM 等等,額外的內部碎片最終可能並不那麼重要。

對於複製操作,SSIS 或基本 T-SQL 都可以正常工作(SSIS 選項可能效率較低,但以後可能更容易維護)。如果您在最後創建 FK 關係以及索引,則無論哪種情況,您都可以執行簡單的“為每個表複製”。當然,一次性收縮+重組可能也很好,但我只是想嚇唬人們不要考慮定期收縮!(我知道人們每天都安排他們)。

引用自:https://dba.stackexchange.com/questions/17277