Sql-Server

害怕 ShrinkDB 那麼這個替代方案可以嗎?

  • October 12, 2017

我已經閱讀了太多的恐怖故事,甚至無法觸及其中的任何 T-SQL 命令SHRINK,但我需要整理出一些我的 SQL Server 2008 數據庫膨脹。

我的數據庫由一組簡單的表組成,這些表中添加了主鍵和標準索引。

考慮到上述情況,我創建了以下內容:

DECLARE @sourcedb NVARCHAR(MAX) = N'DB100';
DECLARE @destdb NVARCHAR(MAX) = N'DB200';
DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'SELECT * INTO ' + @destdb + '.dbo.' + name + 
              ' FROM ' + @sourcedb + '.dbo.' + name + ';' FROM sys.tables;
EXEC sp_executesql @sql;
GO

use DB200

-- Re-add Primary Keys
ALTER TABLE table1 ADD PRIMARY KEY (TRANSID);
ALTER TABLE table2 ADD PRIMARY KEY (ADMINID);
etc etc

-- Re-Add Indexes
CREATE INDEX [TRANSID] ON [table1] ([TRANSID])
GO

CREATE INDEX [PERSONID] ON [table1] ([PERSONID])
GO

CREATE INDEX [AGEID] ON [table1] ([AGEID])
GO

etc etc

然後我的計劃是備份新數據庫並在黃昏時分將其恢復到舊數據庫上。

早期測試表明,一個 365MB 的數據庫下降到 147MB,一切似乎都還不錯。

你能看出我的計劃有什麼陷阱嗎?

隨著時間的推移,有可能從我的數據庫中刪除很多行,因為使用者只需點擊幾下即可刪除冗餘資訊,因此我假設選擇/插入選項僅複製目前在每個表中的行因此,過去的臃腫被拋在了一邊。

定期收縮數據庫不是一個好主意。

在大量數據被永久刪除後收縮數據庫是很有意義的。

不收縮數據庫的主要原因有兩個:

  1. **碎片:**當您告訴 SQL Server 縮小數據文件時,它必須在文件末尾釋放空間。它通過移動文件末尾的任何頁面以盡可能接近文件開頭來實現這一點。這會導致您的索引和表碎片化。

對索引/表進行碎片整理需要一定量的可用空間。而且,碎片整理也可以釋放空間。因此,在對數據庫進行碎片整理之後,您可能會擁有您所見過的最多的可用空間。這使得縮小數據庫變得很誘人。這使得它所以你需要對其進行碎片整理。你看到這裡的惡性循環。 2. 重新增長的成本:另一個問題是,如果您的數據庫已經增長到其目前大小,那麼在某些時候需要所有空間。 它可能不是每天都需要的,但在某些時候需要它。您可能有一個需要額外空間的程序(例如,如上所述,碎片整理;或者,每晚將數據載入到臨時表中進行處理)。

如果您將數據文件縮小到小於正常維護所需的大小,則需要重新增長。如果您打開了即時文件實例化,這不會像其他情況下那樣昂貴。但是,這對您的日誌文件沒有幫助;如果你縮小它,它必須在它必須增長時將新文件空間歸零。

您可以手動調整磁碟空間,如果您的所有文件都達到一周所需的大小,那麼您的磁碟空間就會不足。這可能是一個有效的臨時解決方案(如果有一些性能問題)。但是,如果其中任何一項是手動完成的?你最好不要去度假,因為在你回來之前事情會爆炸。

現在,如前所述,有充分的理由(和好方法)來縮小數據庫。如果你已經大大減少了數據庫中的數據量,而且很長一段時間都不會增長,那麼釋放空間供其他用途是非常有意義的。

對於您所說的,收縮和碎片整理可能比將所有內容複製到新數據庫更快。它幾乎肯定更安全。對於您的計劃,您必須確保原始數據庫中的所有內容都在新數據庫中就位。複製包含外鍵的表意味著您必須確保以正確的順序複製數據。

一些提示:

  • 如果您知道即將發生重大事件(例如,為新的行銷活動載入數百萬行),現在不要擔心縮小。
  • 永遠不要使用DBCC SHRINKDATABASE; SQL Server 決定收縮哪些文件,無論是數據、日誌還是其他文件。您想控制釋放的空間。使用DBCC SHRINKFILE.
  • 雖然您絕對應該在生產中執行此操作之前進行測試執行,但要意識到(除非您的測試數據庫是生產數據庫的恢復)測試中的情況不一定反映生產中的情況。
  • 雖然我認為這比您的新計劃更安全,但為了安全起見,在開始之前進行備份並不是一個壞主意。
  • DBCC SHRINKFILE可能不會阻止生產活動。再說一次,它可能。在計劃中斷期間進行計劃是最安全的。
  • 在收縮完成後,計劃對數據庫進行碎片整理作為中斷的一部分。在此期間數據庫可能會增長一些;沒關係,應該保留額外的空間。

所以我對空間使用率下降的主要原因的預感是由於索引/表碎片。在舊數據庫上查詢sys.dm_db_index_physical_stats然後與新數據庫上的相同查詢進行比較。檢查 col avg_page_space_used_in_percent(使用模式=詳細)

相反,也許定期使用 ALTER INDEX … REBUILD/REORGANIZE 來維護索引。這種方法也應該比複製和重新創建索引更快。將來刪除後,您也將釋放空間。

希望這會有所幫助。

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