1. 程式人生 > >記一次SQL Server的清理過程

記一次SQL Server的清理過程

由於歷史原因,庫裡有幾張表的行數已經超過了幾億條,而且99%都是無用的歷史資料(別問我為什麼這麼多,就是這麼刺激),簡單的top 1查詢都能跑個十幾分鍾。
以上,是背景。

業務上來看,伺服器已經完全無法工作了,所以選擇了停機維護。

第一步,使用獲取總行數

select count(0) from t1

悲催的跑了10分鐘還沒得出結果,放棄了。。。
因為表內的業務資料具有時效性,所以選擇直接清表。
兩種方式,delete和truncate

delete from t1;
truncate table t1;

delete是DML命令,刪除資料會寫事務日誌,對磁碟、記憶體影響較大,而且很慢,但是支援條件刪除(這個是優點,但是這次用不到)。
truncate是DDL命令,刪除資料,效率較高不鎖資料庫寫日誌較小,看起來比較適合我們。

但是!!!

表裡的資料實在是太大了,truncate跑了1個半小時還沒跑完。。趕時間啊兄弟,只能把你kill掉了!

好在truncate取消是不會回滾的,結束truncate之後發現表裡只有900w+的資料,起碼還是有效果的。

重點來了,在結束truncate table t1之前,我們對另外一張億級行數的表t2做了drop操作,1s就結束了,然後用備份的結構重建了t2,真是美滋滋。。。

drop table t2

這玩意就是清理超大表的神器!(生產環境慎用)

資料清理結束了,下面就是資料庫收縮了,把佔用的空間資源釋放出來。
先檢視使用情況:

USE 你的庫名;
GO
-- 資料庫空間使用情況
EXEC sp_spaceused; -- 查下檔案空間使用情況 SELECT file_id, name, [檔案大小(MB)] = size / 128., [未使用空間(MB)] = (size - FILEPROPERTY(name, N'SpaceUsed')) / 128. FROM sys.database_files -- 表空間使用情況 DECLARE @tb_size TABLE( name sysname, rows int, size varchar(100), data_size varchar(100), INDEX_size varchar
(100), unused_size varchar(100) );
INSERT @tb_size EXEC sp_msforeachtable ' sp_spaceused ''?'' ' SELECT * FROM @tb_size

檢查過資料檔案和log檔案之後,按照實際使用情況進行收縮

DBCC SHRINKFILE (N'邏輯檔名' , 10) -- targe size單位是m