1. 程式人生 > >sqlserver 刪除表佔用空間隨筆

sqlserver 刪除表佔用空間隨筆

sqlserver伺服器的硬碟空間只有幾個G了,嘗試清理下表佔用空間

SELECT   a.name, b.rows
FROM      sysobjects AS a INNER JOIN
                 sysindexes AS b ON a.id = b.id
WHERE   (a.type = 'u') AND (b.indid IN (0, 1))
ORDER BY b.rows DESC


看了下排名前幾的表,條數很多(此處犯了一個錯誤,不應該查條數,而應該查表佔用空間)

嘗試刪除一些歷史的記錄數,網上查了下,直接根據條件刪影響太大,所以迴圈刪除,每次刪除1W條,由於這是個按天分割槽的分割槽表,所以再加上分割槽,sql如下:

set rowcount 0;
declare @count int;
set @count = datepart(dayofyear,'2017-08-05');
while 1 = 1
begin
	while 1 = 1
	begin
	delete top(10000) from custom_file_given_Index_log where day = @count;
	if @@ROWCOUNT < 10000
	break;
	end
select @count = @count + 1;
if @count = datepart(dayofyear,'2017-10-01')
break;
end

刪除了大概1千多萬的資料後,發現硬碟空間沒有變化,反而可用空間還少了1G,嘗試考慮其他方式

經過網上查詢,使用如下語句查看錶佔用空間:

exec sp_spaceused 'acce_error_log'
exec sp_spaceused 'acce_insert_log'
exec sp_spaceused 'custom_file_given_Index_log'
exec sp_spaceused 'comm_issue_log'

發現是其中兩個表佔用的資料空間特別大,改為刪除這兩張表的資料,由於是按天分割槽的,考慮使用直接刪除分割槽的方法,這樣速率比較快,前提條件是先做一個跟要刪除表結構一致的臨時表,然後switch要刪除分割槽的記錄到臨時表,再TRUNCATE臨時表:

TRUNCATE TABLE [commlog].[dbo].[comm_issue_log_temp]

ALTER TABLE [dbo].[comm_issue_log]
SWITCH PARTITION datepart(dayofyear,'2018-02-27')
TO [dbo].[comm_issue_log_temp]

TRUNCATE TABLE [commlog].[dbo].[acce_error_log_temp]

刪除完後發現硬碟空間並沒有變化,然後查詢資料庫佔用的空間:

Exec sp_spaceused

發現有Unallocated空間變大,經查資料,這是未分配空間,即資料庫已經佔用了的硬碟空間,但是並沒有分配給任何物件和庫,而unused空間指的是資料庫已經分配了物件,只是物件的增長速度還沒有佔滿這塊空間點選開啟連結

後來發現DBA已經做了定時任務,此問題暫時不再處理