2017-09-16 55 views
0

我有一個SQL Server 2012標準數據庫(恢復模型是「簡單」)以下PipelineArchives表:SQL服務器 - 刪除行高效

enter image description here

表持有Body列歸檔數據。隨着時間的推移,這種增長現在已經包含了11,914行,總共有53gb的數據。我想要執行一個查詢,刪除當前日期之前的所有具有CreatedOn值的行 - 3個月。

我試圖運行

DELETE FROM PipelineArchives 
WHERE CreatedOn < MyDate 

MyDate條件的結果在幾行,那麼查詢執行在幾秒鐘內從SSMS確定。但是,增加229行的日期需要30秒。

是否有更有效的方法來刪除行?

+0

對不起 - 什麼是EAV? –

+1

將>當前日期 - 3個月的行復制到另一個表中。刪除原始表,重命名.... –

+2

[EAV =實體屬性值](https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model) –

回答

2

您可以遞增刪除,它將防止對錶的鎖定並允許其他事務運行。它會使用更多的CPU和內存,但更精通。

DECLARE @archiveId BIGINT 

WHILE (SELECT COUNT(*) FROM PipelineArchives WHERE CreatedOn < MyDate) > 0 
BEGIN 

    SELECT TOP 1 @archiveId = PipelineArchiveId 
    FROM PipelineArchives 
    WHERE CreatedOn < MyDate 

    DELETE PipelineArchives 
    WHERE PipelineArchiveId = @archiveId 

END 
+1

每次計算條目的效率都低於檢查條件是否存在行('WHERE EXISTS(SELECT ...)')。另外:'刪除頂部(1)...'而不是先選擇ID。 –

+0

TT你是正確的,你不是真的想每一次都計算生產表。然而,邏輯是精通的方式。您可以更改循環並使用@counter變量。 – mvisser

0

有時候正確的做法是做相反的事情。

創建一個新表PipelineArchivesNew並從PipelilneArchiveswhere CreatedOn >= MyDate複製行。一旦在新表格中包含所有需要的數據,請將PipelineArchives重命名爲PipelineArchivesOldPipelineArchivesNewPipelineArchives。然後放下PipelineArchivesOld

根據系統的安裝方式,這可能是也可能不是一個很好的解決方案。

+0

非常糟糕的主意。如果這是你的生產表。怎麼樣你的索引,觸發器或安全許可在桌子上。這些都沒有被複制,你必須重新設置它。 – mvisser

0

也可以嘗試不變量:

SET ROWCOUNT 5 

WHILE (SELECT COUNT(*) FROM PipelineArchives WHERE CreatedOn < MyDate) > 0 
BEGIN 
    DELETE PipelineArchives 
    FROM PipelineArchives 
    WHERE CreatedOn < MyDate 
END 

SET ROWCOUNT 0