Sql-Server

減小數據庫的大小

  • May 6, 2019

SQL Server 新手在這裡。我是一個 MySQL 人。我正在為他們的 2008 SQL Server 中的客戶查看一些東西,需要一些建議。設計數據庫的人選擇記錄大量的東西,從不刷新那些日誌表。

最大的表儲存XML來自應用程序和 eBay 等網站的 API 之間交易的完整文件。我只能假設大約 230 GB 的數據庫會損害性能。我猜這些表不會在應用程序中查詢,但即便如此,我也不喜歡這麼龐大的數據庫的想法。清除日誌表後,我預計總剩餘大小約為 30GB。

我想要一些關於如何解決這個問題的建議。從我對這個主題的閱讀來看,刪除一堆數據後,數據庫文件不會自動縮小大小。我還讀到縮小和重新索引是不好的。

  • 這個大型數據庫是否會損害其他表的性能?
  • 我應該為此做點什麼嗎?
  • 我怎樣才能安全地做一些可以提高性能的事情?

如果您要繼續在此數據庫中記錄數據,那麼您最不想做的就是縮小數據庫文件(然後執行索引維護,這將需要它再次增長)。不要介意這些收縮和增長操作會干擾性能,並且最終結果不會讓您比開始時更好。

由於文件只會再次增長,因此這是一個非常徒勞的操作 - 就像還在淋浴時擦乾。你打算用你暫時釋放的所有磁碟空間做什麼?將其出租給另一個應用程序,直到數據庫需要再次增長?當然不是。如果數據庫增長到那個大小一次,它會再次增長到那個大小,但是重用文件中的空間會更有效率,而不需要文件本身的所有這些不必要的收縮-增長-收縮-增長過山車.

即使您將日誌記錄表移動到另一個數據庫,您也應該盡您所能將數據文件預分配到可以容納您想要保存的日誌記錄量的大小(無論是一周、一個月,您有什麼)。通過每天清除數據來保持這個數據庫的精簡,並且不再擔心收縮和重新索引。如果你的大小合適,應該總是有一些可用空間,但沒有過多的可用空間。如果你需要重新索引(你不應該真的,如果你的聚集索引是基於日期時間或其他單調的),在清除之後這樣做(當你有最多的可用空間時),而不是在收縮之後(當你擁有最少的時候)。

您可以按照 Mark 的建議進行操作,而無需向應用程序引入新數據庫,或者根本不更改應用程序或其與數據庫的介面(當然,一項重要的更改是刪除任何外鍵或其他依賴於數據庫的功能) . 您可以簡單地在新數據庫中創建表,然後向目前數據庫中的表添加一個INSTEAD OF INSERT 觸發器(我假設日誌表沒有更新,但您可能還需要一個 INSTEAD OF DELETE 觸發器如果您不直接控制執行清除的過程)。這將有助於寫入,但您必須將讀取指向其他地方,因為沒有 INSTEAD OF SELECT 觸發器。另一種選擇是重命名現有表並創建同義詞甚至是指向新表的視圖。


如果您需要清理已經增長的日誌表,我會避免單個原子事務,例如:

DELETE dbo.logs_table WHERE [datetime] < '20121201';

這將導致大量的日誌增長,並且需要很長時間。相反,您可以將清理分成塊,例如

BEGIN TRANSACTION;

SELECT 1;

WHILE @@ROWCOUNT > 0
BEGIN
 COMMIT TRANSACTION;

 -- if in simple: CHECKPOINT
 -- otherwise: BACKUP LOG

 BEGIN TRANSACTION;

 DELETE TOP (1000) FROM dbo.logs_table WHERE [datetime] < '20121201';
END

我隨意選擇了 1000 和 12 月 1 日,我不知道什麼最適合您的情況。關鍵是您希望保持事務簡短和包含,並在清理表時防止任何長期影響。我過去使用的另一個選項,不是刪除表中 99% 的垃圾,而是將要保留的 1% 移動到新表並刪除舊表。

BEGIN TRANSACTION;

SELECT * 
 INTO dbo.new_logs_table 
 FROM dbo.logs_table
 WHERE [datetime] >= '20121201'

COMMIT TRANSACTION;

-- create indexes/constraints/triggers on dbo.new_logs_table

BEGIN TRANSACTION;
 DROP TABLE dbo.logs_table;
 EXEC sp_rename N'dbo.new_logs_table', N'logs_table', N'OBJECT';
COMMIT TRANSACTION;

如果您說日誌從未被清除過,那麼您很可能處於這樣一種情況,即數據庫的大小將不會再需要(例如,如果您只打算保留一周)一次日誌)。在這種情況下,我可能會進行收縮操作,但前提是確實有必要(例如,您確實需要空間用於其他目的)。一堆空頁面不會影響您的備份或其他操作,並且這些頁面最終將被完全釋放並重用。

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