Performance

到“DBCC SHRINKDATABASE”還是不到“DBCC SHRINKDATABASE”:這就是問題所在

  • August 23, 2018

我們正在釋放 SQL Server 2008 R2 數據庫中的大量空間——Loooot!足以關心-(我們正在丟棄大量不必要的數據)。但數據庫文件保留其文件大小。我們想重新獲得它。

我聽說過很多次使用DBCC SHRINKDATABASE會降低數據庫的性能 - 據我所知,因為“……收縮操作不會保留數據庫中索引的碎片狀態,並且通常會將碎片增加到程度”$$ MSDN $$

所以我打算使用DBCC SHRINKDATABASE然後重建我們的索引。

不使用DBCC SHRINKDATABASE來重新獲得磁碟空間還有另一個性能原因嗎?

來自Tibor Karaszi 的部落格

那麼問題是什麼?為什麼我不應該定期收縮數據庫文件?查看下面的列表,然後您可以自己確定是否要定期收縮數據庫文件:

  • 移動的每個頁面都將記錄到事務日誌中。假設您有一個具有 50GB 已用空間(數據和索引頁面)的數據庫,收縮會將 40GB 隨機排列到文件的開頭。此收縮操作的日誌文件將需要 40GB,可能會自動增長到該大小(如果日誌文件中還沒有 40GB 的可用空間)。以下日誌備份大小為 40GB,加上“正常”日誌記錄。如果數據庫處於簡單恢復模式,這似乎不會發生,可能是因為 CHECKPOINT 會在收縮期間定期修剪日誌。(適用於數據文件的收縮。)
  • 縮小後,隨著使用者在數據庫中添加行等,文件必須再次增長。增長數據庫文件是一項昂貴的操作,它需要時間並且還會損害性能(大量資源使用)。此外,一些修改將被阻止,直到增長操作完成。(適用於數據和日誌文件的收縮。)
  • SQL Server 2005 及更高版本:從 SQL Server 2005 開始,我們有“即時文件初始化”,這意味著可以創建數據庫文件並且還可以快速增長,因為 Windows 不會“清零”數據庫文件中的數據。即時文件初始化僅適用於數據文件,不適用於日誌文件。此外,實例文件初始化要求 SQL Server 服務的服務帳戶具有 SE_MANAGE_VOLUME_NAME windows 特權,可以使用“執行卷維護任務”安全策略進行分配。預設情況下,這僅授予管理員。
  • 在某些情況下,自動增長不會“趕上”空間使用要求。這將導致在執行修改時來自 SQL Server 的錯誤消息返回到客戶端應用程序:如果數據已滿,則返回錯誤 1105;如果日誌已滿,則返回 9002。(適用於數據和日誌文件的收縮。)
  • 移動數據頁會使您的數據庫碎片化。假設您重建索引(這將需要數據庫中的可用空間),然後收縮數據庫。收縮將基本上撤消索引重建,留下碎片索引。不相信我?這很容易自己測試。
  • 如果你反過來做,先收縮,然後重建怎麼辦?好吧,rebuld 需要數據庫中的可用空間用於重建的最大索引,並且很可能您有一個帶有聚集索引的大表。我的一個朋友有一個 4GB 已用空間的數據庫,其中幾乎所有空間都是一個 4GB 的表。他進行了縮小然後重建,重建後立即將數據庫大小“提升”到 8GB。(適用於數據文件的收縮。)
  • 數據庫文件的大量收縮和增長將使您的文件系統碎片化,這將進一步損害性能。(適用於數據和日誌文件的收縮。)
  • 事務日誌文件的反复壓縮和後續增長通常會導致許多虛擬日誌文件,這可能會導致數據庫啟動時間過長。這可能表現為數據庫啟動時間長、恢復時間長、事務複製延遲等。查看這篇博文了解更多資訊。

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