簡體   English   中英

改善sql的刪除性能並減少日志文件和tempDB的大小?

[英]improve sql delete performance and reduce log file and tempDB size?

我有一個龐大的數據庫,它每天處理電子郵件流量。 在系統中,它每天需要刪除一些舊電子郵件:

Delete from EmailList(nolock) 
WHERE EmailId IN ( 
    SELECT EmailId 
    FROM Emails 
    WHERE EmailDate < DATEADD([days], -60, GETDATE())
)

它可以工作,但是問題是:這需要很長時間才能完成,因此日志文件變得非常大。 日志文件大小每天增加超過100GB。

我想我們可以將其更改為

Delete from EmailList(nolock) 
WHERE EXISTS ( 
    SELECT EmailId 
    FROM Emails 
    WHERE (Emails.EmailId = EmailList.EmailId) AND 
        (EmailDate < DATEADD([days], -60, GETDATE()))
)

但是除此之外,我們還有什么可以改善性能的。 最重要的是,減少日志文件的大小?

  • EmailId已建立索引。

我見過

GetDate()-60

樣式語法比

DATEADD([days], -60, GETDATE()))

特別是在日期列上有索引的情況下。 我和一些DBA同事花了很多時間試圖理解為什么它會表現更好,但是結果卻出在布丁上。

考慮到我認為必須刪除的記錄量,您可能要考慮的另一件事是將刪除內容分批處理,例如1000或10000條記錄。 這可能會加快刪除過程。

[編輯]:

關於@TomTom的評論:如果您有可用的SQL Server Enterprise版本,則應使用Table Partitioning

如果不是這種情況,我的原始帖子可能會有所幫助:


[原帖]

刪除大量數據始終很困難。 我遇到了同樣的問題,並采取了以下解決方案:

根據您的要求,這可能不起作用,但是也許您可以從中獲得一些想法。

代替使用1個表,使用具有相同架構的2個表 創建一個指向“ 2個表的活動表(活動方式,這是您當前寫入的表)”的同義詞(我假設您正在使用MS SQL Server)。對該應用程序中的插入使用此同義詞,或者無需使用同義詞,應用程序只需在寫入表的每x天更改一次表即可。

每隔x天,您都可以截斷舊的/不活動的表 ,然后重新創建同義詞以定位被刪節的表(如果使用synonnym解決方案),因此可以有效地每次對數據進行分區。

您必須同步活動表的切換。 通過為應用程序使用共享的App-lock和更改同義詞時的Exclusive Applock(===在切換過程中阻止了編寫應用程序),我完全實現了自動化。

如果不能選擇更改應用程序的代碼,請考慮使用相同的原理,但是可以使用代替觸發器的視圖來創建同義詞(插入操作將插入到“活動”分區中),而不是編寫同義詞。 觸發代碼將需要使用如上所述的Applock之類的方法進行同步(以便在切換過程中進行寫操作)。

我的解決方案要復雜得多,所以我目前無法在此處發布代碼,但是對於高負載應用程序,它可以正常工作,並且切換/清理過程是完全自動化的。

您是否嘗試過按日期進行分區,那么就可以刪除不再感興趣的日期的表版本。 給定一個“休”數據庫,您肯定會運行SQL Server企業版(畢竟,休大於很大),並且該數據庫具有表分區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM