記一次SQL Server的清理過程
阿新 • • 發佈:2019-01-26
由於歷史原因,庫裡有幾張表的行數已經超過了幾億條,而且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